Patrick Williams | b48b7b4 | 2016-08-17 15:04:38 -0500 | [diff] [blame^] | 1 | From b49c8e6e66801406520d1bff791c66dff7b1cddb Mon Sep 17 00:00:00 2001 |
| 2 | From: Li xin <lixin.fnst@cn.fujitsu.com> |
| 3 | Date: Tue, 18 Nov 2014 18:10:20 +0900 |
| 4 | Subject: [PATCH 3/5] rarpd.c : bug fix |
| 5 | |
| 6 | Signed-off-by: Li Xin <lixin.fnst@cn.fujitsu.com> |
| 7 | --- |
| 8 | rarpd.c | 98 +++++++++++++++++++++++++++++++++++++---------------------------- |
| 9 | 1 file changed, 56 insertions(+), 42 deletions(-) |
| 10 | |
| 11 | diff --git a/rarpd.c b/rarpd.c |
| 12 | index 335d2d2..d45300e 100644 |
| 13 | --- a/rarpd.c |
| 14 | +++ b/rarpd.c |
| 15 | @@ -7,9 +7,11 @@ |
| 16 | * 2 of the License, or (at your option) any later version. |
| 17 | * |
| 18 | * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
| 19 | + * Jakub Jelinek, <jakub@redhat.com> |
| 20 | */ |
| 21 | |
| 22 | #include <stdio.h> |
| 23 | +#include <stdlib.h> |
| 24 | #include <syslog.h> |
| 25 | #include <dirent.h> |
| 26 | #include <malloc.h> |
| 27 | @@ -26,6 +28,8 @@ |
| 28 | #include <net/if.h> |
| 29 | #include <net/if_arp.h> |
| 30 | #include <netinet/in.h> |
| 31 | +#include <netinet/ether.h> |
| 32 | +#include <asm/types.h> |
| 33 | #include <linux/if_packet.h> |
| 34 | #include <linux/filter.h> |
| 35 | |
| 36 | @@ -39,27 +43,26 @@ int only_ethers; |
| 37 | int all_ifaces; |
| 38 | int listen_arp; |
| 39 | char *ifname; |
| 40 | -char *tftp_dir = "/etc/tftpboot"; |
| 41 | +char *tftp_dir = "/tftpboot"; |
| 42 | |
| 43 | -extern int ether_ntohost(char *name, unsigned char *ea); |
| 44 | void usage(void) __attribute__((noreturn)); |
| 45 | |
| 46 | -struct iflink |
| 47 | +struct rarpiflink |
| 48 | { |
| 49 | - struct iflink *next; |
| 50 | - int index; |
| 51 | - int hatype; |
| 52 | - unsigned char lladdr[16]; |
| 53 | - unsigned char name[IFNAMSIZ]; |
| 54 | - struct ifaddr *ifa_list; |
| 55 | + struct rarpiflink *next; |
| 56 | + int index; |
| 57 | + int hatype; |
| 58 | + unsigned char lladdr[16]; |
| 59 | + unsigned char name[IFNAMSIZ]; |
| 60 | + struct rarpifaddr *ifa_list; |
| 61 | } *ifl_list; |
| 62 | |
| 63 | -struct ifaddr |
| 64 | +struct rarpifaddr |
| 65 | { |
| 66 | - struct ifaddr *next; |
| 67 | - __u32 prefix; |
| 68 | - __u32 mask; |
| 69 | - __u32 local; |
| 70 | + struct rarpifaddr *next; |
| 71 | + __u32 prefix; |
| 72 | + __u32 mask; |
| 73 | + __u32 local; |
| 74 | }; |
| 75 | |
| 76 | struct rarp_map |
| 77 | @@ -87,8 +90,8 @@ void load_if() |
| 78 | { |
| 79 | int fd; |
| 80 | struct ifreq *ifrp, *ifend; |
| 81 | - struct iflink *ifl; |
| 82 | - struct ifaddr *ifa; |
| 83 | + struct rarpiflink *ifl; |
| 84 | + struct rarpifaddr *ifa; |
| 85 | struct ifconf ifc; |
| 86 | struct ifreq ibuf[256]; |
| 87 | |
| 88 | @@ -144,7 +147,7 @@ void load_if() |
| 89 | continue; |
| 90 | } |
| 91 | |
| 92 | - ifl = (struct iflink*)malloc(sizeof(*ifl)); |
| 93 | + ifl = (struct rarpiflink*)malloc(sizeof(*ifl)); |
| 94 | if (ifl == NULL) |
| 95 | continue; |
| 96 | memset(ifl, 0, sizeof(*ifl)); |
| 97 | @@ -154,6 +157,7 @@ void load_if() |
| 98 | ifl->hatype = ifrp->ifr_hwaddr.sa_family; |
| 99 | memcpy(ifl->lladdr, ifrp->ifr_hwaddr.sa_data, 14); |
| 100 | strncpy(ifl->name, ifrp->ifr_name, IFNAMSIZ); |
| 101 | + ifl->name[IFNAMSIZ-1] = 0; |
| 102 | p = strchr(ifl->name, ':'); |
| 103 | if (p) |
| 104 | *p = 0; |
| 105 | @@ -179,7 +183,7 @@ void load_if() |
| 106 | if (ifa == NULL) { |
| 107 | if (mask == 0 || prefix == 0) |
| 108 | continue; |
| 109 | - ifa = (struct ifaddr*)malloc(sizeof(*ifa)); |
| 110 | + ifa = (struct rarpifaddr*)malloc(sizeof(*ifa)); |
| 111 | memset(ifa, 0, sizeof(*ifa)); |
| 112 | ifa->local = addr; |
| 113 | ifa->prefix = prefix; |
| 114 | @@ -207,6 +211,7 @@ void load_if() |
| 115 | } |
| 116 | } |
| 117 | } |
| 118 | + close(fd); |
| 119 | } |
| 120 | |
| 121 | void configure() |
| 122 | @@ -225,20 +230,21 @@ int bootable(__u32 addr) |
| 123 | d = opendir(tftp_dir); |
| 124 | if (d == NULL) { |
| 125 | syslog(LOG_ERR, "opendir: %m"); |
| 126 | - return 0; |
| 127 | + goto done_bootable; |
| 128 | } |
| 129 | while ((dent = readdir(d)) != NULL) { |
| 130 | if (strncmp(dent->d_name, name, 8) == 0) |
| 131 | break; |
| 132 | } |
| 133 | +done_bootable: |
| 134 | closedir(d); |
| 135 | return dent != NULL; |
| 136 | } |
| 137 | |
| 138 | -struct ifaddr *select_ipaddr(int ifindex, __u32 *sel_addr, __u32 **alist) |
| 139 | +struct rarpifaddr *select_ipaddr(int ifindex, __u32 *sel_addr, __u32 **alist) |
| 140 | { |
| 141 | - struct iflink *ifl; |
| 142 | - struct ifaddr *ifa; |
| 143 | + struct rarpiflink *ifl; |
| 144 | + struct rarpifaddr *ifa; |
| 145 | int retry = 0; |
| 146 | int i; |
| 147 | |
| 148 | @@ -294,7 +300,7 @@ struct rarp_map *rarp_lookup(int ifindex, int hatype, |
| 149 | |
| 150 | if (r == NULL) { |
| 151 | if (hatype == ARPHRD_ETHER && halen == 6) { |
| 152 | - struct ifaddr *ifa; |
| 153 | + struct rarpifaddr *ifa; |
| 154 | struct hostent *hp; |
| 155 | char ename[256]; |
| 156 | static struct rarp_map emap = { |
| 157 | @@ -304,7 +310,7 @@ struct rarp_map *rarp_lookup(int ifindex, int hatype, |
| 158 | 6, |
| 159 | }; |
| 160 | |
| 161 | - if (ether_ntohost(ename, lladdr) != 0 || |
| 162 | + if (ether_ntohost(ename, (struct ether_addr *)lladdr) != 0 || |
| 163 | (hp = gethostbyname(ename)) == NULL) { |
| 164 | if (verbose) |
| 165 | syslog(LOG_INFO, "not found in /etc/ethers"); |
| 166 | @@ -345,7 +351,7 @@ static int load_arp_bpflet(int fd) |
| 167 | |
| 168 | int put_mylladdr(unsigned char **ptr_p, int ifindex, int alen) |
| 169 | { |
| 170 | - struct iflink *ifl; |
| 171 | + struct rarpiflink *ifl; |
| 172 | |
| 173 | for (ifl=ifl_list; ifl; ifl = ifl->next) |
| 174 | if (ifl->index == ifindex) |
| 175 | @@ -362,8 +368,8 @@ int put_mylladdr(unsigned char **ptr_p, int ifindex, int alen) |
| 176 | int put_myipaddr(unsigned char **ptr_p, int ifindex, __u32 hisipaddr) |
| 177 | { |
| 178 | __u32 laddr = 0; |
| 179 | - struct iflink *ifl; |
| 180 | - struct ifaddr *ifa; |
| 181 | + struct rarpiflink *ifl; |
| 182 | + struct rarpifaddr *ifa; |
| 183 | |
| 184 | for (ifl=ifl_list; ifl; ifl = ifl->next) |
| 185 | if (ifl->index == ifindex) |
| 186 | @@ -388,7 +394,7 @@ void arp_advise(int ifindex, unsigned char *lladdr, int lllen, __u32 ipaddr) |
| 187 | int fd; |
| 188 | struct arpreq req; |
| 189 | struct sockaddr_in *sin; |
| 190 | - struct iflink *ifl; |
| 191 | + struct rarpiflink *ifl; |
| 192 | |
| 193 | for (ifl=ifl_list; ifl; ifl = ifl->next) |
| 194 | if (ifl->index == ifindex) |
| 195 | @@ -421,6 +427,10 @@ void serve_it(int fd) |
| 196 | struct rarp_map *rmap; |
| 197 | unsigned char *ptr; |
| 198 | int n; |
| 199 | + int i; |
| 200 | + char tmpbuf[16*3]; |
| 201 | + char tmpname[IFNAMSIZ]; |
| 202 | + struct rarpiflink *ifl; |
| 203 | |
| 204 | n = recvfrom(fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&sll, &sll_len); |
| 205 | if (n<0) { |
| 206 | @@ -447,21 +457,23 @@ void serve_it(int fd) |
| 207 | if (a->ar_op != htons(ARPOP_RREQUEST)) |
| 208 | return; |
| 209 | |
| 210 | - if (verbose) { |
| 211 | - int i; |
| 212 | - char tmpbuf[16*3]; |
| 213 | - char *ptr = tmpbuf; |
| 214 | - for (i=0; i<sll.sll_halen; i++) { |
| 215 | - if (i) { |
| 216 | - sprintf(ptr, ":%02x", sll.sll_addr[i]); |
| 217 | - ptr++; |
| 218 | - } else |
| 219 | - sprintf(ptr, "%02x", sll.sll_addr[i]); |
| 220 | - ptr += 2; |
| 221 | - } |
| 222 | - syslog(LOG_INFO, "RARP request from %s on if%d", tmpbuf, sll.sll_ifindex); |
| 223 | + ptr = tmpbuf; |
| 224 | + snprintf(tmpbuf, 2, "%02x", sll.sll_addr[0]); |
| 225 | + for (ptr=tmpbuf+2, i=1; i<sll.sll_halen; i++) { |
| 226 | + snprintf(ptr, 3, ":%02x", sll.sll_addr[i]); |
| 227 | + ptr += 3; |
| 228 | } |
| 229 | |
| 230 | + for (ifl=ifl_list; ifl; ifl = ifl->next) |
| 231 | + if (ifl->index == sll.sll_ifindex) |
| 232 | + break; |
| 233 | + if (ifl) { |
| 234 | + strncpy(tmpname, ifl->name, IFNAMSIZ); |
| 235 | + tmpname[IFNAMSIZ-1] = 0; |
| 236 | + } else |
| 237 | + sprintf(tmpname, "if%d", sll.sll_ifindex); |
| 238 | + syslog(LOG_INFO, "RARP request from %s on %s", tmpbuf, tmpname); |
| 239 | + |
| 240 | /* Sanity checks */ |
| 241 | |
| 242 | /* 1. IP only -> pln==4 */ |
| 243 | @@ -526,6 +538,8 @@ void serve_it(int fd) |
| 244 | ptr += rmap->lladdr_len; |
| 245 | memcpy(ptr, &rmap->ipaddr, 4); |
| 246 | ptr += 4; |
| 247 | + syslog(LOG_INFO, "RARP response to %s %s on %s", tmpbuf, |
| 248 | + inet_ntoa(*(struct in_addr *)&rmap->ipaddr), tmpname); |
| 249 | |
| 250 | /* Update our ARP cache. Probably, this guy |
| 251 | will not able to make ARP (if it is broken) |
| 252 | @@ -613,7 +627,7 @@ int main(int argc, char **argv) |
| 253 | if (ifname) { |
| 254 | struct ifreq ifr; |
| 255 | memset(&ifr, 0, sizeof(ifr)); |
| 256 | - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); |
| 257 | + strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1); |
| 258 | if (ioctl(pset[0].fd, SIOCGIFINDEX, &ifr)) { |
| 259 | perror("ioctl(SIOCGIFINDEX)"); |
| 260 | usage(); |
| 261 | -- |
| 262 | 1.8.4.2 |
| 263 | |