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