1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* 2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * arpd.c ARP helper daemon. 3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * This program is free software; you can redistribute it and/or 5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * modify it under the terms of the GNU General Public License 6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * as published by the Free Software Foundation; either version 7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 2 of the License, or (at your option) any later version. 8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */ 11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h> 13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h> 14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <malloc.h> 15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h> 16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h> 17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h> 18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netdb.h> 1916efac57d05a43382b63daa96b0ea67114b2c837osdl.org!shemminger#include <db_185.h> 20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/ioctl.h> 21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/poll.h> 22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <errno.h> 23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h> 24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/uio.h> 25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h> 26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/time.h> 27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <time.h> 28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <signal.h> 29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if.h> 3017ce7fd51ca7d1e1b288a64b6edfa54b608a6650osdl.net!shemminger#include <linux/if_ether.h> 31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_arp.h> 32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h> 33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h> 34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_packet.h> 35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/filter.h> 36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "libnetlink.h" 38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h" 39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint resolve_hosts; 41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerDB *dbase; 43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerchar *dbname = "/var/lib/arpd/arpd.db"; 44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 45ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemmingerint ifnum; 46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint *ifvec; 47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerchar **ifnames; 48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstruct dbkey 50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 iface; 52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 addr; 53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}; 54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define IS_NEG(x) (((__u8*)(x))[0] == 0xFF) 56ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger#define NEG_TIME(x) (((x)[2]<<24)|((x)[3]<<16)|((x)[4]<<8)|(x)[5]) 57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define NEG_AGE(x) ((__u32)time(NULL) - NEG_TIME((__u8*)x)) 58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define NEG_VALID(x) (NEG_AGE(x) < negative_timeout) 59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define NEG_CNT(x) (((__u8*)(x))[1]) 60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstruct rtnl_handle rth; 62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstruct pollfd pset[2]; 64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint udp_sock = -1; 65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervolatile int do_exit; 67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervolatile int do_sync; 68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervolatile int do_stats; 69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstruct { 71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long arp_new; 72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long arp_change; 73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long app_recv; 75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long app_success; 76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long app_bad; 77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long app_neg; 78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long app_suppressed; 79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long kern_neg; 81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long kern_new; 82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long kern_change; 83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long probes_sent; 85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned long probes_suppressed; 86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} stats; 87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint active_probing; 89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint negative_timeout = 60; 90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint no_kernel_broadcasts; 91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint broadcast_rate = 1000; 92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint broadcast_burst = 3000; 930df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemmingerint poll_timeout = 30000; 94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid usage(void) 96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, 980df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger "Usage: arpd [ -lkh? ] [ -a N ] [ -b dbase ] [ -B number ]" 990df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger " [ -f file ] [ -n time ] [-p interval ] [ -R rate ] [ interfaces ]\n"); 100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint handle_if(int ifindex) 104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int i; 106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ifnum == 0) 108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 1; 109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (i=0; i<ifnum; i++) 111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ifvec[i] == ifindex) 112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 1; 113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint sysctl_adjusted; 117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid do_sysctl_adjustments(void) 119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int i; 121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!ifnum) 123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (i=0; i<ifnum; i++) { 126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char buf[128]; 127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger FILE *fp; 128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (active_probing) { 130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprintf(buf, "/proc/sys/net/ipv4/neigh/%s/mcast_solicit", ifnames[i]); 131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((fp = fopen(buf, "w")) != NULL) { 132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (no_kernel_broadcasts) 133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(buf, "0\n"); 134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else 135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprintf(buf, "%d\n", active_probing>=2 ? 1 : 3-active_probing); 136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fputs(buf, fp); 137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fclose(fp); 138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprintf(buf, "/proc/sys/net/ipv4/neigh/%s/app_solicit", ifnames[i]); 142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((fp = fopen(buf, "w")) != NULL) { 143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprintf(buf, "%d\n", active_probing<=1 ? 1 : active_probing); 144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fputs(buf, fp); 145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fclose(fp); 146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sysctl_adjusted = 1; 149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid undo_sysctl_adjustments(void) 152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int i; 154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!sysctl_adjusted) 156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (i=0; i<ifnum; i++) { 159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char buf[128]; 160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger FILE *fp; 161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (active_probing) { 163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprintf(buf, "/proc/sys/net/ipv4/neigh/%s/mcast_solicit", ifnames[i]); 164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((fp = fopen(buf, "w")) != NULL) { 165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(buf, "3\n"); 166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fputs(buf, fp); 167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fclose(fp); 168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sprintf(buf, "/proc/sys/net/ipv4/neigh/%s/app_solicit", ifnames[i]); 171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((fp = fopen(buf, "w")) != NULL) { 172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcpy(buf, "0\n"); 173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fputs(buf, fp); 174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fclose(fp); 175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sysctl_adjusted = 0; 178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint send_probe(int ifindex, __u32 addr) 182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_in dst; 185f332d169246447bd5e258ac03d5ee840a70adb1eshemminger socklen_t len; 186aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned char buf[256]; 187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct arphdr *ah = (struct arphdr*)buf; 188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned char *p = (unsigned char *)(ah+1); 189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_ll sll; 190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr.ifr_ifindex = ifindex; 193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(udp_sock, SIOCGIFNAME, &ifr)) 194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(udp_sock, SIOCGIFHWADDR, &ifr)) 196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) 198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (setsockopt(udp_sock, SOL_SOCKET, SO_BINDTODEVICE, ifr.ifr_name, strlen(ifr.ifr_name)+1) < 0) 200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dst.sin_family = AF_INET; 203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dst.sin_port = htons(1025); 204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dst.sin_addr.s_addr = addr; 205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (connect(udp_sock, (struct sockaddr*)&dst, sizeof(dst)) < 0) 206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger len = sizeof(dst); 208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (getsockname(udp_sock, (struct sockaddr*)&dst, &len) < 0) 209aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ah->ar_hrd = htons(ifr.ifr_hwaddr.sa_family); 212aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ah->ar_pro = htons(ETH_P_IP); 213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ah->ar_hln = 6; 214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ah->ar_pln = 4; 215aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ah->ar_op = htons(ARPOP_REQUEST); 216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 217aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memcpy(p, ifr.ifr_hwaddr.sa_data, ah->ar_hln); 218aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger p += ah->ar_hln; 219aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 220aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memcpy(p, &dst.sin_addr, 4); 221aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger p+=4; 222aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 223aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sll.sll_family = AF_PACKET; 224aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(sll.sll_addr, 0xFF, sizeof(sll.sll_addr)); 225aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sll.sll_ifindex = ifindex; 226aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sll.sll_protocol = htons(ETH_P_ARP); 227aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memcpy(p, &sll.sll_addr, ah->ar_hln); 228aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger p+=ah->ar_hln; 229aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 230aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memcpy(p, &addr, 4); 231aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger p+=4; 232aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 233f332d169246447bd5e258ac03d5ee840a70adb1eshemminger if (sendto(pset[0].fd, buf, p-buf, 0, (struct sockaddr*)&sll, sizeof(sll)) < 0) 234aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 235aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.probes_sent++; 236aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 237aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 238aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 239aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* Be very tough on sending probes: 1 per second with burst of 3. */ 240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint queue_active_probe(int ifindex, __u32 addr) 242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 243aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger static struct timeval prev; 244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger static int buckets; 245aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct timeval now; 246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger gettimeofday(&now, NULL); 248aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (prev.tv_sec) { 249aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int diff = (now.tv_sec-prev.tv_sec)*1000+(now.tv_usec-prev.tv_usec)/1000; 250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger buckets += diff; 251aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 252aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger buckets = broadcast_burst; 253aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 254aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (buckets > broadcast_burst) 255aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger buckets = broadcast_burst; 256aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (buckets >= broadcast_rate && !send_probe(ifindex, addr)) { 257aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger buckets -= broadcast_rate; 258aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger prev = now; 259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 260aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.probes_suppressed++; 262aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 264aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 265aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint respond_to_kernel(int ifindex, __u32 addr, char *lla, int llalen) 266aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct { 268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct nlmsghdr n; 269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ndmsg ndm; 270aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char buf[256]; 271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } req; 272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&req.n, 0, sizeof(req.n)); 274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&req.ndm, 0, sizeof(req.ndm)); 275aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 276aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); 277aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.n.nlmsg_flags = NLM_F_REQUEST; 278aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.n.nlmsg_type = RTM_NEWNEIGH; 279aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.ndm.ndm_family = AF_INET; 280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.ndm.ndm_state = NUD_STALE; 281aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.ndm.ndm_ifindex = ifindex; 282aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.ndm.ndm_type = RTN_UNICAST; 283aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 284aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4); 285aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen); 2866cf8398f5f487762586801c25539d8fe5bb33b39Stephen Hemminger return rtnl_send(&rth, &req, req.n.nlmsg_len) <= 0; 287aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 288aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 289aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid prepare_neg_entry(__u8 *ndata, __u32 stamp) 290aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 291aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ndata[0] = 0xFF; 292aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ndata[1] = 0; 293aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ndata[2] = stamp>>24; 294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ndata[3] = stamp>>16; 295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ndata[4] = stamp>>8; 296aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ndata[5] = stamp; 297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 298aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 299aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 300aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_one_request(struct nlmsghdr *n) 301aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 302aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ndmsg *ndm = NLMSG_DATA(n); 303aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int len = n->nlmsg_len; 304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtattr * tb[NDA_MAX+1]; 305aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct dbkey key; 306aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DBT dbkey, dbdat; 307aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int do_acct = 0; 308aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n->nlmsg_type == NLMSG_DONE) { 310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->sync(dbase, 0); 311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 312aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger /* Now we have at least mirror of kernel db, so that 313aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * may start real resolution. 314aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */ 315aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_sysctl_adjustments(); 316aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 317aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 318aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 319aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n->nlmsg_type != RTM_GETNEIGH && n->nlmsg_type != RTM_NEWNEIGH) 320aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 321aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 322aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger len -= NLMSG_LENGTH(sizeof(*ndm)); 323aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (len < 0) 324aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 325aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 326aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ndm->ndm_family != AF_INET || 327aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (ifnum && !handle_if(ndm->ndm_ifindex)) || 328aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ndm->ndm_flags || 329aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ndm->ndm_type != RTN_UNICAST || 330aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger !(ndm->ndm_state&~NUD_NOARP)) 331aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 332aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 333aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len); 334aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 335aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!tb[NDA_DST]) 336aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 337aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 338aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger key.iface = ndm->ndm_ifindex; 339aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memcpy(&key.addr, RTA_DATA(tb[NDA_DST]), 4); 340aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.data = &key; 341aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.size = sizeof(key); 342aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 343aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbase->get(dbase, &dbkey, &dbdat, 0) != 0) { 344aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.data = 0; 345aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.size = 0; 346aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 347aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 348aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n->nlmsg_type == RTM_GETNEIGH) { 349aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!(n->nlmsg_flags&NLM_F_REQUEST)) 350aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 351aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 352aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!(ndm->ndm_state&(NUD_PROBE|NUD_INCOMPLETE))) { 353aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.app_bad++; 354aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 355aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 356aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 357aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ndm->ndm_state&NUD_PROBE) { 358aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger /* If we get this, kernel still has some valid 359aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * address, but unicast probing failed and host 360aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * is either dead or changed its mac address. 361aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Kernel is going to initiate broadcast resolution. 362aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * OK, we invalidate our information as well. 363aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */ 364aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbdat.data && !IS_NEG(dbdat.data)) 365aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.app_neg++; 366aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 367aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->del(dbase, &dbkey, 0); 368aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 369aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger /* If we get this kernel does not have any information. 370aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * If we have something tell this to kernel. */ 371aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.app_recv++; 372aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbdat.data && !IS_NEG(dbdat.data)) { 373aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.app_success++; 374aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger respond_to_kernel(key.iface, key.addr, dbdat.data, dbdat.size); 375aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 376aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 377aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 378aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger /* Sheeit! We have nothing to tell. */ 379aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger /* If we have recent negative entry, be silent. */ 380aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbdat.data && NEG_VALID(dbdat.data)) { 381aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (NEG_CNT(dbdat.data) >= active_probing) { 382aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.app_suppressed++; 383aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 384aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 385aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_acct = 1; 386aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 387aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 388aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 389aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (active_probing && 390aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger queue_active_probe(ndm->ndm_ifindex, key.addr) == 0 && 391aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_acct) { 392aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEG_CNT(dbdat.data)++; 393aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->put(dbase, &dbkey, &dbdat, 0); 394aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 395aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (n->nlmsg_type == RTM_NEWNEIGH) { 396aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n->nlmsg_flags&NLM_F_REQUEST) 397aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 398aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 399aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ndm->ndm_state&NUD_FAILED) { 400aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger /* Kernel was not able to resolve. Host is dead. 401aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Create negative entry if it is not present 402aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * or renew it if it is too old. */ 403aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!dbdat.data || 404aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger !IS_NEG(dbdat.data) || 405aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger !NEG_VALID(dbdat.data)) { 406aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u8 ndata[6]; 407aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.kern_neg++; 408aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger prepare_neg_entry(ndata, time(NULL)); 409aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.data = ndata; 410aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.size = sizeof(ndata); 411aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->put(dbase, &dbkey, &dbdat, 0); 412aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 413aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (tb[NDA_LLADDR]) { 414aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbdat.data && !IS_NEG(dbdat.data)) { 415aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (memcmp(RTA_DATA(tb[NDA_LLADDR]), dbdat.data, dbdat.size) == 0) 416aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 417aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.kern_change++; 418aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 419aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.kern_new++; 420aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 421aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.data = RTA_DATA(tb[NDA_LLADDR]); 422aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.size = RTA_PAYLOAD(tb[NDA_LLADDR]); 423aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->put(dbase, &dbkey, &dbdat, 0); 424aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 425aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 426aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 427aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 428aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 429aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid load_initial_table(void) 430aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 431aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger rtnl_wilddump_request(&rth, AF_INET, RTM_GETNEIGH); 432aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 433aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 434aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid get_kern_msg(void) 435aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 436aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int status; 437aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct nlmsghdr *h; 438aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_nl nladdr; 439aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct iovec iov; 440aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char buf[8192]; 441aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct msghdr msg = { 442aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (void*)&nladdr, sizeof(nladdr), 443aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger &iov, 1, 444aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NULL, 0, 445aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 0 446aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger }; 447aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 448aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&nladdr, 0, sizeof(nladdr)); 449aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 450aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger iov.iov_base = buf; 451aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger iov.iov_len = sizeof(buf); 452aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 453aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger status = recvmsg(rth.fd, &msg, MSG_DONTWAIT); 454aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 455aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (status <= 0) 456aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 457aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 458aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (msg.msg_namelen != sizeof(nladdr)) 459aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 460aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 461aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (nladdr.nl_pid) 462aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 463aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 464aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { 465aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int len = h->nlmsg_len; 466aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int l = len - sizeof(*h); 467aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 468aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (l < 0 || len > status) 469aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 470aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 471aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_one_request(h) < 0) 472aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 473aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 474aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger status -= NLMSG_ALIGN(len); 475aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); 476aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 477aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 478aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 479aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* Receive gratuitous ARP messages and store them, that's all. */ 480aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid get_arp_pkt(void) 481aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 482aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned char buf[1024]; 483aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_ll sll; 484f332d169246447bd5e258ac03d5ee840a70adb1eshemminger socklen_t sll_len = sizeof(sll); 485aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct arphdr *a = (struct arphdr*)buf; 486aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct dbkey key; 487aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DBT dbkey, dbdat; 488aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int n; 489aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 490ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger n = recvfrom(pset[0].fd, buf, sizeof(buf), MSG_DONTWAIT, 491f332d169246447bd5e258ac03d5ee840a70adb1eshemminger (struct sockaddr*)&sll, &sll_len); 492aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n < 0) { 493aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (errno != EINTR && errno != EAGAIN) 494aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger syslog(LOG_ERR, "recvfrom: %m"); 495aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 496aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 497aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 498aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ifnum && !handle_if(sll.sll_ifindex)) 499aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 500aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 501aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger /* Sanity checks */ 502aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 503aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n < sizeof(*a) || 504aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (a->ar_op != htons(ARPOP_REQUEST) && 505aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger a->ar_op != htons(ARPOP_REPLY)) || 506aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger a->ar_pln != 4 || 507aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger a->ar_pro != htons(ETH_P_IP) || 508aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger a->ar_hln != sll.sll_halen || 509aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sizeof(*a) + 2*4 + 2*a->ar_hln > n) 510aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 511aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 512aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger key.iface = sll.sll_ifindex; 513aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memcpy(&key.addr, (char*)(a+1) + a->ar_hln, 4); 514aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 515ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger /* DAD message, ignore. */ 516aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (key.addr == 0) 517aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 518aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 519aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.data = &key; 520aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.size = sizeof(key); 521aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 522aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbase->get(dbase, &dbkey, &dbdat, 0) == 0 && !IS_NEG(dbdat.data)) { 523aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (memcmp(dbdat.data, a+1, dbdat.size) == 0) 524aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 525aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.arp_change++; 526aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 527aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.arp_new++; 528aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 529aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 530aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.data = a+1; 531aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.size = a->ar_hln; 532aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->put(dbase, &dbkey, &dbdat, 0); 533aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 534aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 535aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid catch_signal(int sig, void (*handler)(int)) 536aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 537aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sigaction sa; 538aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 539aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&sa, 0, sizeof(sa)); 540aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sa.sa_handler = handler; 541aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#ifdef SA_INTERRUPT 542aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sa.sa_flags = SA_INTERRUPT; 543ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger#endif 544aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sigaction(sig, &sa, NULL); 545aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 546aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 547aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <setjmp.h> 548aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingersigjmp_buf env; 549aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervolatile int in_poll; 550aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 551aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid sig_exit(int signo) 552aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 553aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_exit = 1; 554aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (in_poll) 555aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger siglongjmp(env, 1); 556aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 557aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 558aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid sig_sync(int signo) 559aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 560aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_sync = 1; 561aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (in_poll) 562aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger siglongjmp(env, 1); 563aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 564aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 565aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid sig_stats(int signo) 566aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 567aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_sync = 1; 568aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_stats = 1; 569aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (in_poll) 570aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger siglongjmp(env, 1); 571aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 572aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 573aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid send_stats(void) 574aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 575aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger syslog(LOG_INFO, "arp_rcv: n%lu c%lu app_rcv: tot %lu hits %lu bad %lu neg %lu sup %lu", 576aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.arp_new, stats.arp_change, 577aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 578aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.app_recv, stats.app_success, 579aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.app_bad, stats.app_neg, stats.app_suppressed 580aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ); 581aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger syslog(LOG_INFO, "kern: n%lu c%lu neg %lu arp_send: %lu rlim %lu", 582aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.kern_new, stats.kern_change, stats.kern_neg, 583aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 584aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.probes_sent, stats.probes_suppressed 585aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ); 586aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_stats = 0; 587aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 588aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 589aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 590aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint main(int argc, char **argv) 591aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 592aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int opt; 593aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int do_list = 0; 594aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *do_load = NULL; 595aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 5960df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger while ((opt = getopt(argc, argv, "h?b:lf:a:n:p:kR:B:")) != EOF) { 597aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger switch (opt) { 598aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'b': 599aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbname = optarg; 600aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 601aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'f': 602aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_load) { 603aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Duplicate option -f\n"); 604aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 605aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 606aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_load = optarg; 607aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 608aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'l': 609aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_list = 1; 610aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 611aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'a': 612aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger active_probing = atoi(optarg); 613aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 614aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'n': 615aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger negative_timeout = atoi(optarg); 616aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 617aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'k': 618aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger no_kernel_broadcasts = 1; 619aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 6200df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger case 'p': 6210df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger if ((poll_timeout = 1000 * strtod(optarg, NULL)) < 100) { 6220df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger fprintf(stderr,"Invalid poll timeout\n"); 6230df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger exit(-1); 6240df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger } 6250df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger break; 626aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'R': 627aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((broadcast_rate = atoi(optarg)) <= 0 || 628aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (broadcast_rate = 1000/broadcast_rate) <= 0) { 629aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Invalid ARP rate\n"); 630aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 631aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 632aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 633aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'B': 634aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((broadcast_burst = atoi(optarg)) <= 0 || 635aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (broadcast_burst = 1000*broadcast_burst) <= 0) { 636aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Invalid ARP burst\n"); 637aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 638aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 639aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 640aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'h': 641aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case '?': 642aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger default: 643aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 644aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 645aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 646aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc -= optind; 647aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argv += optind; 648aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 649aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc > 0) { 650aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifnum = argc; 651aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifnames = argv; 652aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifvec = malloc(argc*sizeof(int)); 653aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!ifvec) { 654aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("malloc"); 655aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 656aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 657aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 658aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 659aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((udp_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 660aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("socket"); 661aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 662aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 663aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 664aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ifnum) { 665aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int i; 666aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 667aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 668aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (i=0; i<ifnum; i++) { 669aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ); 670aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) { 671aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("ioctl(SIOCGIFINDEX)"); 672aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1);; 673aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 674aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifvec[i] = ifr.ifr_ifindex; 675aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 676aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 677aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 678aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase = dbopen(dbname, O_CREAT|O_RDWR, 0644, DB_HASH, NULL); 679aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbase == NULL) { 680aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("db_open"); 681aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 682aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 683aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 684aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_load) { 685aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char buf[128]; 686aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger FILE *fp; 687aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct dbkey k; 688aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DBT dbkey, dbdat; 689aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 690aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.data = &k; 691aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.size = sizeof(k); 692aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 693aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(do_load, "-") == 0 || strcmp(do_load, "--") == 0) { 694aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fp = stdin; 695aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if ((fp = fopen(do_load, "r")) == NULL) { 696aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("fopen"); 697aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 698aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 699aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 700aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger buf[sizeof(buf)-1] = 0; 701aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (fgets(buf, sizeof(buf)-1, fp)) { 702aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u8 b1[6]; 703aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char ipbuf[128]; 704aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char macbuf[128]; 705aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 706aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (buf[0] == '#') 707aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger continue; 708aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 709aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (sscanf(buf, "%u%s%s", &k.iface, ipbuf, macbuf) != 3) { 710aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Wrong format of input file \"%s\"\n", do_load); 711aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 712aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 713aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strncmp(macbuf, "FAILED:", 7) == 0) 714aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger continue; 715aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!inet_aton(ipbuf, (struct in_addr*)&k.addr)) { 716aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Invalid IP address: \"%s\"\n", ipbuf); 717aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 718aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 719f332d169246447bd5e258ac03d5ee840a70adb1eshemminger 720aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.data = hexstring_a2n(macbuf, b1, 6); 721aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbdat.data == NULL) 722aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 723aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.size = 6; 724aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 725aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbase->put(dbase, &dbkey, &dbdat, 0)) { 726aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("hash->put"); 727aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 728aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 729aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 730aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->sync(dbase, 0); 731aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fp != stdin) 732aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fclose(fp); 733aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 734aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 735aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_list) { 736aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DBT dbkey, dbdat; 737aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf("%-8s %-15s %s\n", "#Ifindex", "IP", "MAC"); 738aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (dbase->seq(dbase, &dbkey, &dbdat, R_NEXT) == 0) { 739ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger struct dbkey *key = dbkey.data; 740aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (handle_if(key->iface)) { 741aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!IS_NEG(dbdat.data)) { 742f332d169246447bd5e258ac03d5ee840a70adb1eshemminger char b1[18]; 743aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf("%-8d %-15s %s\n", 744aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger key->iface, 745aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger inet_ntoa(*(struct in_addr*)&key->addr), 746aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger hexstring_n2a(dbdat.data, 6, b1, 18)); 747aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 748aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf("%-8d %-15s FAILED: %dsec ago\n", 749aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger key->iface, 750aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger inet_ntoa(*(struct in_addr*)&key->addr), 751aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEG_AGE(dbdat.data)); 752aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 753aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 754aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 755aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 756aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 757aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_load || do_list) 758aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto out; 759aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 760aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[0].fd = socket(PF_PACKET, SOCK_DGRAM, 0); 761aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (pset[0].fd < 0) { 762aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("socket"); 763aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 764aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 765aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 766aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (1) { 767aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_ll sll; 768aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&sll, 0, sizeof(sll)); 769aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sll.sll_family = AF_PACKET; 770aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sll.sll_protocol = htons(ETH_P_ARP); 771aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sll.sll_ifindex = (ifnum == 1 ? ifvec[0] : 0); 772aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (bind(pset[0].fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) { 773aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("bind"); 774aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 775aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 776aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 777aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 778aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_open(&rth, RTMGRP_NEIGH) < 0) { 779aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("rtnl_open"); 780aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 781aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 782aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[1].fd = rth.fd; 783aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 784aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger load_initial_table(); 785aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 786a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger if (daemon(0, 0)) { 787a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger perror("arpd: daemon"); 788a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger goto do_abort; 789aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 790aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 791aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger openlog("arpd", LOG_PID | LOG_CONS, LOG_DAEMON); 792aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger catch_signal(SIGINT, sig_exit); 793aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger catch_signal(SIGTERM, sig_exit); 794aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger catch_signal(SIGHUP, sig_sync); 795aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger catch_signal(SIGUSR1, sig_stats); 796aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 797aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define EVENTS (POLLIN|POLLPRI|POLLERR|POLLHUP) 798aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[0].events = EVENTS; 799aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[0].revents = 0; 800aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[1].events = EVENTS; 801aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[1].revents = 0; 802aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 803aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sigsetjmp(env, 1); 804aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 805aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (;;) { 806aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger in_poll = 1; 807aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 808aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_exit) 809aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 810aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_sync) { 811aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger in_poll = 0; 812aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->sync(dbase, 0); 813aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_sync = 0; 814aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger in_poll = 1; 815aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 816aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_stats) 817aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger send_stats(); 8180df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger if (poll(pset, 2, poll_timeout) > 0) { 819aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger in_poll = 0; 820aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (pset[0].revents&EVENTS) 821aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger get_arp_pkt(); 822aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (pset[1].revents&EVENTS) 823aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger get_kern_msg(); 824aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 825aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_sync = 1; 826aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 827aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 828aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 829aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger undo_sysctl_adjustments(); 830aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerout: 831aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->close(dbase); 832aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(0); 833aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 834aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerdo_abort: 835aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->close(dbase); 836aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 837aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 838