1313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* 2313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * rarpd.c RARP daemon. 3313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 4313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * This program is free software; you can redistribute it and/or 5313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * modify it under the terms of the GNU General Public License 6313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * as published by the Free Software Foundation; either version 7313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 2 of the License, or (at your option) any later version. 8313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 9313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 11313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 12313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <stdio.h> 13313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <syslog.h> 14313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <dirent.h> 15313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <malloc.h> 16313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <string.h> 17313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <unistd.h> 18313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <stdlib.h> 19313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netdb.h> 20313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <arpa/inet.h> 21313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/ioctl.h> 22313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/poll.h> 23313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/errno.h> 24313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/fcntl.h> 25313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/socket.h> 26313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/signal.h> 27313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <linux/if.h> 28313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <linux/if_arp.h> 29313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/in.h> 30313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <linux/if_packet.h> 31313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <linux/filter.h> 32313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 33313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint do_reload = 1; 34313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 35313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint debug; 36313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint verbose; 37313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint ifidx; 38313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint allow_offlink; 39313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint only_ethers; 40313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint all_ifaces; 41313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint listen_arp; 42313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittichar *ifname; 43313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittichar *tftp_dir = "/etc/tftpboot"; 44313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 45313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiextern int ether_ntohost(char *name, unsigned char *ea); 46313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid usage(void) __attribute__((noreturn)); 47313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 48313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct iflink 49313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 50313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct iflink *next; 51313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int index; 52313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int hatype; 53313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti unsigned char lladdr[16]; 54313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char name[IFNAMSIZ]; 55313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifaddr *ifa_list; 56313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} *ifl_list; 57313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 58313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct ifaddr 59313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 60313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifaddr *next; 61313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 prefix; 62313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 mask; 63313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 local; 64313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}; 65313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 66313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct rarp_map 67313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 68313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct rarp_map *next; 69313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 70313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int ifindex; 71313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int arp_type; 72313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int lladdr_len; 73313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti unsigned char lladdr[16]; 74313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 ipaddr; 75313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} *rarp_db; 76313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 77313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid usage() 78313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 79313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti fprintf(stderr, "Usage: rarpd [ -dveaA ] [ -b tftpdir ] [ interface]\n"); 80313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 81313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 82313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 83313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid load_db(void) 84313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 85313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 86313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 87313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid load_if(void) 88313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 89313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int fd; 90313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifreq *ifrp, *ifend; 91313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct iflink *ifl; 92313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifaddr *ifa; 93313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifconf ifc; 94313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifreq ibuf[256]; 95313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 96313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 97313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "socket: %m"); 98313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 99313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 100313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 101313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifc.ifc_len = sizeof ibuf; 102313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifc.ifc_buf = (caddr_t)ibuf; 103313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 || 104313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifc.ifc_len < (int)sizeof(struct ifreq)) { 105313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "SIOCGIFCONF: %m"); 106313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti close(fd); 107313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 108313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 109313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 110313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti while ((ifl = ifl_list) != NULL) { 111313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti while ((ifa = ifl->ifa_list) != NULL) { 112313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifl->ifa_list = ifa->next; 113313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti free(ifa); 114313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 115313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifl_list = ifl->next; 116313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti free(ifl); 117313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 118313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 119313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len); 120313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ifrp = ibuf; ifrp < ifend; ifrp++) { 121313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 addr; 122313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 mask; 123313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 prefix; 124313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 125313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifrp->ifr_addr.sa_family != AF_INET) 126313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 127313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti addr = ((struct sockaddr_in*)&ifrp->ifr_addr)->sin_addr.s_addr; 128313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (addr == 0) 129313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 130313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ioctl(fd, SIOCGIFINDEX, ifrp)) { 131313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "ioctl(SIOCGIFNAME): %m"); 132313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 133313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 134313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifidx && ifrp->ifr_ifindex != ifidx) 135313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 136313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ifl = ifl_list; ifl; ifl = ifl->next) 137313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl->index == ifrp->ifr_ifindex) 138313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 139313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl == NULL) { 140313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char *p; 141313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int index = ifrp->ifr_ifindex; 142313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 143313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ioctl(fd, SIOCGIFHWADDR, ifrp)) { 144313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "ioctl(SIOCGIFHWADDR): %m"); 145313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 146313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 147313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 148313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifl = (struct iflink*)malloc(sizeof(*ifl)); 149313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl == NULL) 150313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 151313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(ifl, 0, sizeof(*ifl)); 152313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifl->next = ifl_list; 153313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifl_list = ifl; 154313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifl->index = index; 155313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifl->hatype = ifrp->ifr_hwaddr.sa_family; 156313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(ifl->lladdr, ifrp->ifr_hwaddr.sa_data, 14); 157313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti strncpy(ifl->name, ifrp->ifr_name, IFNAMSIZ); 158313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p = strchr(ifl->name, ':'); 159313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (p) 160313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *p = 0; 161313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (verbose) 162313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_INFO, "link %s", ifl->name); 163313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 164313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ioctl(fd, SIOCGIFNETMASK, ifrp)) { 165313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "ioctl(SIOCGIFMASK): %m"); 166313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 167313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 168313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti mask = ((struct sockaddr_in*)&ifrp->ifr_netmask)->sin_addr.s_addr; 169313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ioctl(fd, SIOCGIFDSTADDR, ifrp)) { 170313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "ioctl(SIOCGIFDSTADDR): %m"); 171313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 172313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 173313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti prefix = ((struct sockaddr_in*)&ifrp->ifr_dstaddr)->sin_addr.s_addr; 174313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ifa = ifl->ifa_list; ifa; ifa = ifa->next) { 175313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifa->local == addr && 176313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifa->prefix == prefix && 177313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifa->mask == mask) 178313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 179313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 180313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifa == NULL) { 181313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (mask == 0 || prefix == 0) 182313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 183313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifa = (struct ifaddr*)malloc(sizeof(*ifa)); 184313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(ifa, 0, sizeof(*ifa)); 185313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifa->local = addr; 186313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifa->prefix = prefix; 187313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifa->mask = mask; 188313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifa->next = ifl->ifa_list; 189313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifl->ifa_list = ifa; 190313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 191313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (verbose) { 192313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 193313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 m = ~0U; 194313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (i=32; i>=0; i--) { 195313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (htonl(m) == mask) 196313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 197313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti m <<= 1; 198313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 199313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (addr == prefix) { 200313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_INFO, " addr %s/%d on %s\n", 201313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti inet_ntoa(*(struct in_addr*)&addr), i, ifl->name); 202313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 203313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char tmpa[64]; 204313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sprintf(tmpa, "%s", inet_ntoa(*(struct in_addr*)&addr)); 205313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_INFO, " addr %s %s/%d on %s\n", tmpa, 206313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti inet_ntoa(*(struct in_addr*)&prefix), i, ifl->name); 207313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 208313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 209313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 210313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 211313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 212313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 213313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid configure(void) 214313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 215313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti load_if(); 216313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti load_db(); 217313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 218313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 219313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint bootable(__u32 addr) 220313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 221313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct dirent *dent; 222313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti DIR *d; 223313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char name[9]; 224313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 225313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sprintf(name, "%08X", (__u32)ntohl(addr)); 226313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti d = opendir(tftp_dir); 227313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (d == NULL) { 228313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "opendir: %m"); 229313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 230313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 231313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti while ((dent = readdir(d)) != NULL) { 232313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (strncmp(dent->d_name, name, 8) == 0) 233313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 234313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 235313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti closedir(d); 236313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return dent != NULL; 237313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 238313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 239313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct ifaddr *select_ipaddr(int ifindex, __u32 *sel_addr, __u32 **alist) 240313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 241313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct iflink *ifl; 242313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifaddr *ifa; 243313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int retry = 0; 244313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 245313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 246313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiretry: 247313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ifl=ifl_list; ifl; ifl=ifl->next) 248313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl->index == ifindex) 249313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 250313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl == NULL && !retry) { 251313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti retry++; 252313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti load_if(); 253313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti goto retry; 254313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 255313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl == NULL) 256313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return NULL; 257313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 258313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (i=0; alist[i]; i++) { 259313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 addr = *(alist[i]); 260313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ifa=ifl->ifa_list; ifa; ifa=ifa->next) { 261313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!((ifa->prefix^addr)&ifa->mask)) { 262313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *sel_addr = addr; 263313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return ifa; 264313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 265313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 266313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifa == NULL && retry==0) { 267313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti retry++; 268313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti load_if(); 269313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti goto retry; 270313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 271313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 272313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (i==1 && allow_offlink) { 273313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *sel_addr = *(alist[0]); 274313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return ifl->ifa_list; 275313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 276313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "Off-link request on %s", ifl->name); 277313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return NULL; 278313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 279313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 280313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct rarp_map *rarp_lookup(int ifindex, int hatype, 281313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int halen, unsigned char *lladdr) 282313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 283313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct rarp_map *r; 284313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 285313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (r=rarp_db; r; r=r->next) { 286313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (r->arp_type != hatype && r->arp_type != -1) 287313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 288313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (r->lladdr_len != halen) 289313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 290313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (r->ifindex != ifindex && r->ifindex != 0) 291313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 292313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (memcmp(r->lladdr, lladdr, halen) == 0) 293313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 294313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 295313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 296313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (r == NULL) { 297313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (hatype == ARPHRD_ETHER && halen == 6) { 298313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifaddr *ifa; 299313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct hostent *hp; 300313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char ename[256]; 301313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti static struct rarp_map emap = { 302313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti NULL, 303313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 0, 304313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ARPHRD_ETHER, 305313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 6, 306313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }; 307313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 308313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ether_ntohost(ename, lladdr) != 0 || 309313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (hp = gethostbyname(ename)) == NULL) { 310313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (verbose) 311313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_INFO, "not found in /etc/ethers"); 312313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return NULL; 313313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 314313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (hp->h_addrtype != AF_INET) { 315313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "no IP address"); 316313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return NULL; 317313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 318313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifa = select_ipaddr(ifindex, &emap.ipaddr, (__u32 **)hp->h_addr_list); 319313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifa) { 320313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(emap.lladdr, lladdr, 6); 321313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (only_ethers || bootable(emap.ipaddr)) 322313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return &emap; 323313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (verbose) 324313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_INFO, "not bootable"); 325313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 326313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 327313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 328313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return r; 329313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 330313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 331313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int load_arp_bpflet(int fd) 332313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 333313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti static struct sock_filter insns[] = { 334313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6), 335313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, ARPOP_RREQUEST, 0, 1), 336313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti BPF_STMT(BPF_RET|BPF_K, 1024), 337313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti BPF_STMT(BPF_RET|BPF_K, 0), 338313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }; 339313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti static struct sock_fprog filter = { 340313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sizeof insns / sizeof(insns[0]), 341313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti insns 342313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti }; 343313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 344313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)); 345313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 346313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 347313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint put_mylladdr(unsigned char **ptr_p, int ifindex, int alen) 348313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 349313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct iflink *ifl; 350313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 351313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ifl=ifl_list; ifl; ifl = ifl->next) 352313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl->index == ifindex) 353313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 354313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 355313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl==NULL) 356313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 357313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 358313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(*ptr_p, ifl->lladdr, alen); 359313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *ptr_p += alen; 360313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 361313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 362313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 363313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint put_myipaddr(unsigned char **ptr_p, int ifindex, __u32 hisipaddr) 364313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 365313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 laddr = 0; 366313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct iflink *ifl; 367313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifaddr *ifa; 368313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 369313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ifl=ifl_list; ifl; ifl = ifl->next) 370313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl->index == ifindex) 371313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 372313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 373313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl==NULL) 374313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return -1; 375313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 376313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ifa=ifl->ifa_list; ifa; ifa=ifa->next) { 377313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!((ifa->prefix^hisipaddr)&ifa->mask)) { 378313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti laddr = ifa->local; 379313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 380313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 381313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 382313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(*ptr_p, &laddr, 4); 383313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *ptr_p += 4; 384313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 385313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 386313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 387313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid arp_advise(int ifindex, unsigned char *lladdr, int lllen, __u32 ipaddr) 388313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 389313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int fd; 390313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct arpreq req; 391313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct sockaddr_in *sin; 392313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct iflink *ifl; 393313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 394313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ifl=ifl_list; ifl; ifl = ifl->next) 395313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl->index == ifindex) 396313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 397313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 398313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifl == NULL) 399313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 400313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 401313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti fd = socket(AF_INET, SOCK_DGRAM, 0); 402313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&req, 0, sizeof(req)); 403313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti req.arp_flags = ATF_COM; 404313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sin = (struct sockaddr_in *)&req.arp_pa; 405313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sin->sin_family = AF_INET; 406313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sin->sin_addr.s_addr = ipaddr; 407313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti req.arp_ha.sa_family = ifl->hatype; 408313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(req.arp_ha.sa_data, lladdr, lllen); 409313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(req.arp_dev, ifl->name, IFNAMSIZ); 410313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 411313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ioctl(fd, SIOCSARP, &req)) 412313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "SIOCSARP: %m"); 413313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti close(fd); 414313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 415313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 416313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid serve_it(int fd) 417313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 418313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti unsigned char buf[1024]; 419313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct sockaddr_ll sll; 420313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti socklen_t sll_len = sizeof(sll); 421313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct arphdr *a = (struct arphdr*)buf; 422313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct rarp_map *rmap; 423313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti unsigned char *ptr; 424313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int n; 425313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 426313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti n = recvfrom(fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&sll, &sll_len); 427313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (n<0) { 428313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (errno != EINTR && errno != EAGAIN) 429313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "recvfrom: %m"); 430313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 431313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 432313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 433313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Do not accept packets for other hosts and our own ones */ 434313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (sll.sll_pkttype != PACKET_BROADCAST && 435313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sll.sll_pkttype != PACKET_MULTICAST && 436313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sll.sll_pkttype != PACKET_HOST) 437313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 438313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 439313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifidx && sll.sll_ifindex != ifidx) 440313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 441313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 442313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (n<sizeof(*a)) { 443313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "truncated arp packet; len=%d", n); 444313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 445313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 446313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 447313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Accept only RARP requests */ 448313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (a->ar_op != htons(ARPOP_RREQUEST)) 449313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 450313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 451313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (verbose) { 452313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 453313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char tmpbuf[16*3]; 454313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char *ptr = tmpbuf; 455313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (i=0; i<sll.sll_halen; i++) { 456313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (i) { 457313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sprintf(ptr, ":%02x", sll.sll_addr[i]); 458313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ptr++; 459313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else 460313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sprintf(ptr, "%02x", sll.sll_addr[i]); 461313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ptr += 2; 462313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 463313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_INFO, "RARP request from %s on if%d", tmpbuf, sll.sll_ifindex); 464313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 465313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 466313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Sanity checks */ 467313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 468313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* 1. IP only -> pln==4 */ 469313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (a->ar_pln != 4) { 470313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "interesting rarp_req plen=%d", a->ar_pln); 471313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 472313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 473313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* 2. ARP protocol must be IP */ 474313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (a->ar_pro != htons(ETH_P_IP)) { 475313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "rarp protocol is not IP %04x", ntohs(a->ar_pro)); 476313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 477313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 478313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* 3. ARP types must match */ 479313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (htons(sll.sll_hatype) != a->ar_hrd) { 480313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti switch (sll.sll_hatype) { 481313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case ARPHRD_FDDI: 482313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (a->ar_hrd == htons(ARPHRD_ETHER) || 483313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti a->ar_hrd == htons(ARPHRD_IEEE802)) 484313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 485313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti default: 486313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "rarp htype mismatch"); 487313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 488313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 489313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 490313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* 3. LL address lengths must be equal */ 491313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (a->ar_hln != sll.sll_halen) { 492313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "rarp hlen mismatch"); 493313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 494313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 495313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* 4. Check packet length */ 496313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (sizeof(*a) + 2*4 + 2*a->ar_hln > n) { 497313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "truncated rarp request; len=%d", n); 498313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 499313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 500313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* 5. Silly check: if this guy set different source 501313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti addresses in MAC header and in ARP, he is insane 502313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 503313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (memcmp(sll.sll_addr, a+1, sll.sll_halen)) { 504313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "this guy set different his lladdrs in arp and header"); 505313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 506313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 507313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* End of sanity checks */ 508313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 509313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Lookup requested target in our database */ 510313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti rmap = rarp_lookup(sll.sll_ifindex, sll.sll_hatype, 511313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sll.sll_halen, (unsigned char*)(a+1) + sll.sll_halen + 4); 512313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (rmap == NULL) 513313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 514313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 515313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Prepare reply. It is almost ready, we only 516313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti replace ARP packet type, put our lladdr and 517313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti IP address to source fileds, 518313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti and fill target IP address. 519313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 520313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti a->ar_op = htons(ARPOP_RREPLY); 521313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ptr = (unsigned char*)(a+1); 522313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (put_mylladdr(&ptr, sll.sll_ifindex, rmap->lladdr_len)) 523313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 524313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (put_myipaddr(&ptr, sll.sll_ifindex, rmap->ipaddr)) 525313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return; 526313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* It is already filled */ 527313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ptr += rmap->lladdr_len; 528313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(ptr, &rmap->ipaddr, 4); 529313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ptr += 4; 530313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 531313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Update our ARP cache. Probably, this guy 532313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti will not able to make ARP (if it is broken) 533313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 534313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti arp_advise(sll.sll_ifindex, rmap->lladdr, rmap->lladdr_len, rmap->ipaddr); 535313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 536313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Sendto is blocking, but with 5sec timeout */ 537313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti alarm(5); 538313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sendto(fd, buf, ptr - buf, 0, (struct sockaddr*)&sll, sizeof(sll)); 539313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti alarm(0); 540313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 541313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 542313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid catch_signal(int sig, void (*handler)(int)) 543313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 544313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct sigaction sa; 545313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 546313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&sa, 0, sizeof(sa)); 547313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sa.sa_handler = handler; 548313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef SA_INTERRUPT 549313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sa.sa_flags = SA_INTERRUPT; 550313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 551313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sigaction(sig, &sa, NULL); 552313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 553313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 554313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid sig_alarm(int signo) 555313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 556313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 557313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 558313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid sig_hup(int signo) 559313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 560313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti do_reload = 1; 561313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 562313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 563313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint main(int argc, char **argv) 564313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 565313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct pollfd pset[2]; 566313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int psize; 567313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int opt; 568313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 569313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 570313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti opterr = 0; 571313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti while ((opt = getopt(argc, argv, "aAb:dvoe")) != EOF) { 572313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti switch (opt) { 573313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'a': 574313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++all_ifaces; 575313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 576313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 577313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'A': 578313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++listen_arp; 579313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 580313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 581313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'd': 582313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++debug; 583313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 584313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 585313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'v': 586313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++verbose; 587313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 588313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 589313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'o': 590313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++allow_offlink; 591313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 592313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 593313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'e': 594313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++only_ethers; 595313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 596313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 597313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'b': 598313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti tftp_dir = optarg; 599313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 600313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 601313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti default: 602313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti usage(); 603313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 604313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 605313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (argc > optind) { 606313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (argc > optind+1) 607313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti usage(); 608313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifname = argv[optind]; 609313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 610313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 611313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti psize = 1; 612313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[0].fd = socket(PF_PACKET, SOCK_DGRAM, 0); 613313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 614313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ifname) { 615313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ifreq ifr; 616313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&ifr, 0, sizeof(ifr)); 617313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 618313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ioctl(pset[0].fd, SIOCGIFINDEX, &ifr)) { 619313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("ioctl(SIOCGIFINDEX)"); 620313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti usage(); 621313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 622313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ifidx = ifr.ifr_ifindex; 623313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 624313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 625313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[1].fd = -1; 626313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (listen_arp) { 627313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[1].fd = socket(PF_PACKET, SOCK_DGRAM, 0); 628313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (pset[1].fd >= 0) { 629313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti load_arp_bpflet(pset[1].fd); 630313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti psize = 1; 631313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 632313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 633313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 634313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (pset[1].fd >= 0) { 635313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct sockaddr_ll sll; 636313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&sll, 0, sizeof(sll)); 637313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sll.sll_family = AF_PACKET; 638313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sll.sll_protocol = htons(ETH_P_ARP); 639313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sll.sll_ifindex = all_ifaces ? 0 : ifidx; 640313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (bind(pset[1].fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) { 641313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti close(pset[1].fd); 642313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[1].fd = -1; 643313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti psize = 1; 644313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 645313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 646313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (pset[0].fd >= 0) { 647313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct sockaddr_ll sll; 648313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memset(&sll, 0, sizeof(sll)); 649313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sll.sll_family = AF_PACKET; 650313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sll.sll_protocol = htons(ETH_P_RARP); 651313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sll.sll_ifindex = all_ifaces ? 0 : ifidx; 652313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (bind(pset[0].fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) { 653313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti close(pset[0].fd); 654313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[0].fd = -1; 655313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 656313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 657313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (pset[0].fd < 0) { 658313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[0] = pset[1]; 659313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti psize--; 660313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 661313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (psize == 0) { 662313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti fprintf(stderr, "failed to bind any socket. Aborting.\n"); 663313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 664313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 665313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 666313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (!debug) { 667313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int fd; 668313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pid_t pid = fork(); 669313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 670313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (pid > 0) 671313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(0); 672313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti else if (pid == -1) { 673313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("rarpd: fork"); 674313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 675313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 676313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 677313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (chdir("/") < 0) { 678313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("rarpd: chdir"); 679313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 680313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 681313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 682313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti fd = open("/dev/null", O_RDWR); 683313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (fd >= 0) { 684313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti dup2(fd, 0); 685313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti dup2(fd, 1); 686313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti dup2(fd, 2); 687313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (fd > 2) 688313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti close(fd); 689313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 690313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti setsid(); 691313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 692313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 693313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti openlog("rarpd", LOG_PID | LOG_CONS, LOG_DAEMON); 694313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti catch_signal(SIGALRM, sig_alarm); 695313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti catch_signal(SIGHUP, sig_hup); 696313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 697313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (;;) { 698313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 699313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 700313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (do_reload) { 701313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti configure(); 702313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti do_reload = 0; 703313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 704313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 705313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define EVENTS (POLLIN|POLLPRI|POLLERR|POLLHUP) 706313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[0].events = EVENTS; 707313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[0].revents = 0; 708313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[1].events = EVENTS; 709313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pset[1].revents = 0; 710313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 711313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti i = poll(pset, psize, -1); 712313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (i <= 0) { 713313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (errno != EINTR && i<0) { 714313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti syslog(LOG_ERR, "poll returned some crap: %m\n"); 715313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sleep(10); 716313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 717313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 718313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 719313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (i=0; i<psize; i++) { 720313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (pset[i].revents&EVENTS) 721313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti serve_it(pset[i].fd); 722313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 723313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 724313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 725