From b49c8e6e66801406520d1bff791c66dff7b1cddb Mon Sep 17 00:00:00 2001
From: Li xin <lixin.fnst@cn.fujitsu.com>
Date: Tue, 18 Nov 2014 18:10:20 +0900
Subject: [PATCH 3/5] rarpd.c : bug fix

Signed-off-by: Li Xin <lixin.fnst@cn.fujitsu.com>
---
 rarpd.c | 98 +++++++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 56 insertions(+), 42 deletions(-)

diff --git a/rarpd.c b/rarpd.c
index 335d2d2..d45300e 100644
--- a/rarpd.c
+++ b/rarpd.c
@@ -7,9 +7,11 @@
  *		2 of the License, or (at your option) any later version.
  *
  * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ *		Jakub Jelinek, <jakub@redhat.com>
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <syslog.h>
 #include <dirent.h>
 #include <malloc.h>
@@ -26,6 +28,8 @@
 #include <net/if.h>
 #include <net/if_arp.h>
 #include <netinet/in.h>
+#include <netinet/ether.h>
+#include <asm/types.h>
 #include <linux/if_packet.h>
 #include <linux/filter.h>
 
@@ -39,27 +43,26 @@ int only_ethers;
 int all_ifaces;
 int listen_arp;
 char *ifname;
-char *tftp_dir = "/etc/tftpboot";
+char *tftp_dir = "/tftpboot";
 
-extern int ether_ntohost(char *name, unsigned char *ea);
 void usage(void) __attribute__((noreturn));
 
-struct iflink
+struct rarpiflink
 {
-	struct iflink	*next;
-	int	       	index;
-	int		hatype;
-	unsigned char	lladdr[16];
-	unsigned char	name[IFNAMSIZ];
-	struct ifaddr 	*ifa_list;
+	struct rarpiflink	*next;
+	int	       		index;
+	int			hatype;
+	unsigned char		lladdr[16];
+	unsigned char		name[IFNAMSIZ];
+	struct rarpifaddr 	*ifa_list;
 } *ifl_list;
 
-struct ifaddr
+struct rarpifaddr
 {
-	struct ifaddr 	*next;
-	__u32		prefix;
-	__u32		mask;
-	__u32		local;
+	struct rarpifaddr 	*next;
+	__u32			prefix;
+	__u32			mask;
+	__u32			local;
 };
 
 struct rarp_map
@@ -87,8 +90,8 @@ void load_if()
 {
 	int fd;
 	struct ifreq *ifrp, *ifend;
-	struct iflink *ifl;
-	struct ifaddr *ifa;
+	struct rarpiflink *ifl;
+	struct rarpifaddr *ifa;
 	struct ifconf ifc;
 	struct ifreq ibuf[256];
 
@@ -144,7 +147,7 @@ void load_if()
 				continue;
 			}
 
-			ifl = (struct iflink*)malloc(sizeof(*ifl));
+			ifl = (struct rarpiflink*)malloc(sizeof(*ifl));
 			if (ifl == NULL)
 				continue;
 			memset(ifl, 0, sizeof(*ifl));
@@ -154,6 +157,7 @@ void load_if()
 			ifl->hatype = ifrp->ifr_hwaddr.sa_family;
 			memcpy(ifl->lladdr, ifrp->ifr_hwaddr.sa_data, 14);
 			strncpy(ifl->name, ifrp->ifr_name, IFNAMSIZ);
+			ifl->name[IFNAMSIZ-1] = 0;
 			p = strchr(ifl->name, ':');
 			if (p)
 				*p = 0;
@@ -179,7 +183,7 @@ void load_if()
 		if (ifa == NULL) {
 			if (mask == 0 || prefix == 0)
 				continue;
-			ifa = (struct ifaddr*)malloc(sizeof(*ifa));
+			ifa = (struct rarpifaddr*)malloc(sizeof(*ifa));
 			memset(ifa, 0, sizeof(*ifa));
 			ifa->local = addr;
 			ifa->prefix = prefix;
@@ -207,6 +211,7 @@ void load_if()
 			}
 		}
 	}
+	close(fd);
 }
 
 void configure()
@@ -225,20 +230,21 @@ int bootable(__u32 addr)
 	d = opendir(tftp_dir);
 	if (d == NULL) {
 		syslog(LOG_ERR, "opendir: %m");
-		return 0;
+		goto done_bootable;
 	}
 	while ((dent = readdir(d)) != NULL) {
 		if (strncmp(dent->d_name, name, 8) == 0)
 			break;
 	}
+done_bootable:
 	closedir(d);
 	return dent != NULL;
 }
 
-struct ifaddr *select_ipaddr(int ifindex, __u32 *sel_addr, __u32 **alist)
+struct rarpifaddr *select_ipaddr(int ifindex, __u32 *sel_addr, __u32 **alist)
 {
-	struct iflink *ifl;
-	struct ifaddr *ifa;
+	struct rarpiflink *ifl;
+	struct rarpifaddr *ifa;
 	int retry = 0;
 	int i;
 
@@ -294,7 +300,7 @@ struct rarp_map *rarp_lookup(int ifindex, int hatype,
 
 	if (r == NULL) {
 		if (hatype == ARPHRD_ETHER && halen == 6) {
-			struct ifaddr *ifa;
+			struct rarpifaddr *ifa;
 			struct hostent *hp;
 			char ename[256];
 			static struct rarp_map emap = {
@@ -304,7 +310,7 @@ struct rarp_map *rarp_lookup(int ifindex, int hatype,
 				6,
 			};
 
-			if (ether_ntohost(ename, lladdr) != 0 ||
+			if (ether_ntohost(ename, (struct ether_addr *)lladdr) != 0 ||
 			    (hp = gethostbyname(ename)) == NULL) {
 				if (verbose)
 					syslog(LOG_INFO, "not found in /etc/ethers");
@@ -345,7 +351,7 @@ static int load_arp_bpflet(int fd)
 
 int put_mylladdr(unsigned char **ptr_p, int ifindex, int alen)
 {
-	struct iflink *ifl;
+	struct rarpiflink *ifl;
 
 	for (ifl=ifl_list; ifl; ifl = ifl->next)
 		if (ifl->index == ifindex)
@@ -362,8 +368,8 @@ int put_mylladdr(unsigned char **ptr_p, int ifindex, int alen)
 int put_myipaddr(unsigned char **ptr_p, int ifindex, __u32 hisipaddr)
 {
 	__u32 laddr = 0;
-	struct iflink *ifl;
-	struct ifaddr *ifa;
+	struct rarpiflink *ifl;
+	struct rarpifaddr *ifa;
 
 	for (ifl=ifl_list; ifl; ifl = ifl->next)
 		if (ifl->index == ifindex)
@@ -388,7 +394,7 @@ void arp_advise(int ifindex, unsigned char *lladdr, int lllen, __u32 ipaddr)
 	int fd;
 	struct arpreq req;
 	struct sockaddr_in *sin;
-	struct iflink *ifl;
+	struct rarpiflink *ifl;
 
 	for (ifl=ifl_list; ifl; ifl = ifl->next)
 		if (ifl->index == ifindex)
@@ -421,6 +427,10 @@ void serve_it(int fd)
 	struct rarp_map *rmap;
 	unsigned char *ptr;
 	int n;
+	int i;
+	char tmpbuf[16*3];
+	char tmpname[IFNAMSIZ];
+	struct rarpiflink *ifl;
 
 	n = recvfrom(fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&sll, &sll_len);
 	if (n<0) {
@@ -447,21 +457,23 @@ void serve_it(int fd)
 	if (a->ar_op != htons(ARPOP_RREQUEST))
 		return;
 
-	if (verbose) {
-		int i;
-		char tmpbuf[16*3];
-		char *ptr = tmpbuf;
-		for (i=0; i<sll.sll_halen; i++) {
-			if (i) {
-				sprintf(ptr, ":%02x", sll.sll_addr[i]);
-				ptr++;
-			} else
-				sprintf(ptr, "%02x", sll.sll_addr[i]);
-			ptr += 2;
-		}
-		syslog(LOG_INFO, "RARP request from %s on if%d", tmpbuf, sll.sll_ifindex);
+	ptr = tmpbuf;
+        snprintf(tmpbuf, 2, "%02x", sll.sll_addr[0]);
+	for (ptr=tmpbuf+2, i=1; i<sll.sll_halen; i++) {
+		snprintf(ptr, 3, ":%02x", sll.sll_addr[i]);
+		ptr += 3;
 	}
 
+	for (ifl=ifl_list; ifl; ifl = ifl->next)
+		if (ifl->index == sll.sll_ifindex)
+			break;
+	if (ifl) {
+		strncpy(tmpname, ifl->name, IFNAMSIZ);
+		tmpname[IFNAMSIZ-1] = 0;
+	} else
+		sprintf(tmpname, "if%d", sll.sll_ifindex);
+	syslog(LOG_INFO, "RARP request from %s on %s", tmpbuf, tmpname);
+
 	/* Sanity checks */
 
 	/* 1. IP only -> pln==4 */
@@ -526,6 +538,8 @@ void serve_it(int fd)
 	ptr += rmap->lladdr_len;
 	memcpy(ptr, &rmap->ipaddr, 4);
 	ptr += 4;
+	syslog(LOG_INFO, "RARP response to %s %s on %s", tmpbuf,
+	       inet_ntoa(*(struct in_addr *)&rmap->ipaddr), tmpname);
 
 	/* Update our ARP cache. Probably, this guy
 	   will not able to make ARP (if it is broken)
@@ -613,7 +627,7 @@ int main(int argc, char **argv)
         if (ifname) {
 		struct ifreq ifr;
 		memset(&ifr, 0, sizeof(ifr));
-		strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+		strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
 		if (ioctl(pset[0].fd, SIOCGIFINDEX, &ifr)) {
 			perror("ioctl(SIOCGIFINDEX)");
 			usage();
-- 
1.8.4.2

