arpd.c revision d2468da0a317c87ded0a9a0ae6d7d8bc7ab2e4d2
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 95d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void 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 103d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic int 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 118d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void 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 151d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void 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 181d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic int 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 241d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic int 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 265d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic int 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 289d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void 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 300d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic int 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 429d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void load_initial_table(void) 430aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 431d2468da0a317c87ded0a9a0ae6d7d8bc7ab2e4d2Stephen Hemminger if (rtnl_wilddump_request(&rth, AF_INET, RTM_GETNEIGH) < 0) { 432d2468da0a317c87ded0a9a0ae6d7d8bc7ab2e4d2Stephen Hemminger perror("dump request failed"); 433d2468da0a317c87ded0a9a0ae6d7d8bc7ab2e4d2Stephen Hemminger exit(1); 434d2468da0a317c87ded0a9a0ae6d7d8bc7ab2e4d2Stephen Hemminger } 435d2468da0a317c87ded0a9a0ae6d7d8bc7ab2e4d2Stephen Hemminger 436aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 437aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 438d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void get_kern_msg(void) 439aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 440aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int status; 441aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct nlmsghdr *h; 442aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_nl nladdr; 443aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct iovec iov; 444aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char buf[8192]; 445aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct msghdr msg = { 446aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (void*)&nladdr, sizeof(nladdr), 447aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger &iov, 1, 448aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NULL, 0, 449aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 0 450aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger }; 451aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 452aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&nladdr, 0, sizeof(nladdr)); 453aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 454aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger iov.iov_base = buf; 455aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger iov.iov_len = sizeof(buf); 456aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 457aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger status = recvmsg(rth.fd, &msg, MSG_DONTWAIT); 458aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 459aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (status <= 0) 460aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 461aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 462aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (msg.msg_namelen != sizeof(nladdr)) 463aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 464aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 465aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (nladdr.nl_pid) 466aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 467aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 468aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { 469aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int len = h->nlmsg_len; 470aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int l = len - sizeof(*h); 471aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 472aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (l < 0 || len > status) 473aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 474aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 475aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_one_request(h) < 0) 476aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 477aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 478aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger status -= NLMSG_ALIGN(len); 479aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); 480aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 481aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 482aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 483aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* Receive gratuitous ARP messages and store them, that's all. */ 484d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void get_arp_pkt(void) 485aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 486aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned char buf[1024]; 487aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_ll sll; 488f332d169246447bd5e258ac03d5ee840a70adb1eshemminger socklen_t sll_len = sizeof(sll); 489aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct arphdr *a = (struct arphdr*)buf; 490aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct dbkey key; 491aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DBT dbkey, dbdat; 492aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int n; 493aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 494ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger n = recvfrom(pset[0].fd, buf, sizeof(buf), MSG_DONTWAIT, 495f332d169246447bd5e258ac03d5ee840a70adb1eshemminger (struct sockaddr*)&sll, &sll_len); 496aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n < 0) { 497aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (errno != EINTR && errno != EAGAIN) 498aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger syslog(LOG_ERR, "recvfrom: %m"); 499aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 500aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 501aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 502aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ifnum && !handle_if(sll.sll_ifindex)) 503aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 504aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 505aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger /* Sanity checks */ 506aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 507aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n < sizeof(*a) || 508aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (a->ar_op != htons(ARPOP_REQUEST) && 509aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger a->ar_op != htons(ARPOP_REPLY)) || 510aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger a->ar_pln != 4 || 511aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger a->ar_pro != htons(ETH_P_IP) || 512aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger a->ar_hln != sll.sll_halen || 513aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sizeof(*a) + 2*4 + 2*a->ar_hln > n) 514aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 515aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 516aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger key.iface = sll.sll_ifindex; 517aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memcpy(&key.addr, (char*)(a+1) + a->ar_hln, 4); 518aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 519ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger /* DAD message, ignore. */ 520aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (key.addr == 0) 521aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 522aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 523aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.data = &key; 524aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.size = sizeof(key); 525aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 526aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbase->get(dbase, &dbkey, &dbdat, 0) == 0 && !IS_NEG(dbdat.data)) { 527aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (memcmp(dbdat.data, a+1, dbdat.size) == 0) 528aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return; 529aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.arp_change++; 530aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 531aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.arp_new++; 532aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 533aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 534aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.data = a+1; 535aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.size = a->ar_hln; 536aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->put(dbase, &dbkey, &dbdat, 0); 537aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 538aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 539d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void catch_signal(int sig, void (*handler)(int)) 540aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 541aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sigaction sa; 542aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 543aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&sa, 0, sizeof(sa)); 544aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sa.sa_handler = handler; 545aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#ifdef SA_INTERRUPT 546aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sa.sa_flags = SA_INTERRUPT; 547ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger#endif 548aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sigaction(sig, &sa, NULL); 549aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 550aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 551aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <setjmp.h> 552aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingersigjmp_buf env; 553aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervolatile int in_poll; 554aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 555d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void sig_exit(int signo) 556aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 557aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_exit = 1; 558aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (in_poll) 559aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger siglongjmp(env, 1); 560aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 561aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 562d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void sig_sync(int signo) 563aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 564aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_sync = 1; 565aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (in_poll) 566aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger siglongjmp(env, 1); 567aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 568aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 569d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void sig_stats(int signo) 570aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 571aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_sync = 1; 572aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_stats = 1; 573aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (in_poll) 574aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger siglongjmp(env, 1); 575aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 576aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 577d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic void send_stats(void) 578aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 579aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger syslog(LOG_INFO, "arp_rcv: n%lu c%lu app_rcv: tot %lu hits %lu bad %lu neg %lu sup %lu", 580aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.arp_new, stats.arp_change, 581aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 582aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.app_recv, stats.app_success, 583aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.app_bad, stats.app_neg, stats.app_suppressed 584aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ); 585aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger syslog(LOG_INFO, "kern: n%lu c%lu neg %lu arp_send: %lu rlim %lu", 586aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.kern_new, stats.kern_change, stats.kern_neg, 587aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 588aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger stats.probes_sent, stats.probes_suppressed 589aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ); 590aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_stats = 0; 591aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 592aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 593aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 594aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint main(int argc, char **argv) 595aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 596aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int opt; 597aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int do_list = 0; 598aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *do_load = NULL; 599aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 6000df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger while ((opt = getopt(argc, argv, "h?b:lf:a:n:p:kR:B:")) != EOF) { 601aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger switch (opt) { 602aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'b': 603aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbname = optarg; 604aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 605aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'f': 606aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_load) { 607aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Duplicate option -f\n"); 608aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 609aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 610aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_load = optarg; 611aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 612aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'l': 613aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_list = 1; 614aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 615aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'a': 616aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger active_probing = atoi(optarg); 617aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 618aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'n': 619aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger negative_timeout = atoi(optarg); 620aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 621aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'k': 622aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger no_kernel_broadcasts = 1; 623aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 6240df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger case 'p': 6250df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger if ((poll_timeout = 1000 * strtod(optarg, NULL)) < 100) { 6260df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger fprintf(stderr,"Invalid poll timeout\n"); 6270df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger exit(-1); 6280df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger } 6290df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger break; 630aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'R': 631aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((broadcast_rate = atoi(optarg)) <= 0 || 632aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (broadcast_rate = 1000/broadcast_rate) <= 0) { 633aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Invalid ARP rate\n"); 634aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 635aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 636aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 637aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'B': 638aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((broadcast_burst = atoi(optarg)) <= 0 || 639aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (broadcast_burst = 1000*broadcast_burst) <= 0) { 640aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Invalid ARP burst\n"); 641aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 642aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 643aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 644aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case 'h': 645aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case '?': 646aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger default: 647aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 648aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 649aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 650aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc -= optind; 651aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argv += optind; 652aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 653aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc > 0) { 654aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifnum = argc; 655aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifnames = argv; 656aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifvec = malloc(argc*sizeof(int)); 657aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!ifvec) { 658aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("malloc"); 659aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 660aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 661aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 662aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 663aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((udp_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 664aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("socket"); 665aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 666aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 667aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 668aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ifnum) { 669aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int i; 670aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 671aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 672aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (i=0; i<ifnum; i++) { 673aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ); 674aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) { 675aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("ioctl(SIOCGIFINDEX)"); 676aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1);; 677aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 678aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifvec[i] = ifr.ifr_ifindex; 679aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 680aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 681aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 682aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase = dbopen(dbname, O_CREAT|O_RDWR, 0644, DB_HASH, NULL); 683aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbase == NULL) { 684aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("db_open"); 685aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 686aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 687aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 688aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_load) { 689aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char buf[128]; 690aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger FILE *fp; 691aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct dbkey k; 692aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DBT dbkey, dbdat; 693aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 694aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.data = &k; 695aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbkey.size = sizeof(k); 696aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 697aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(do_load, "-") == 0 || strcmp(do_load, "--") == 0) { 698aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fp = stdin; 699aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if ((fp = fopen(do_load, "r")) == NULL) { 700aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("fopen"); 701aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 702aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 703aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 704aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger buf[sizeof(buf)-1] = 0; 705aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (fgets(buf, sizeof(buf)-1, fp)) { 706aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u8 b1[6]; 707aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char ipbuf[128]; 708aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char macbuf[128]; 709aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 710aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (buf[0] == '#') 711aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger continue; 712aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 713aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (sscanf(buf, "%u%s%s", &k.iface, ipbuf, macbuf) != 3) { 714aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Wrong format of input file \"%s\"\n", do_load); 715aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 716aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 717aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strncmp(macbuf, "FAILED:", 7) == 0) 718aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger continue; 719aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!inet_aton(ipbuf, (struct in_addr*)&k.addr)) { 720aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Invalid IP address: \"%s\"\n", ipbuf); 721aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 722aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 723f332d169246447bd5e258ac03d5ee840a70adb1eshemminger 724aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.data = hexstring_a2n(macbuf, b1, 6); 725aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbdat.data == NULL) 726aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 727aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbdat.size = 6; 728aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 729aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dbase->put(dbase, &dbkey, &dbdat, 0)) { 730aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("hash->put"); 731aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 732aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 733aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 734aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->sync(dbase, 0); 735aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fp != stdin) 736aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fclose(fp); 737aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 738aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 739aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_list) { 740aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger DBT dbkey, dbdat; 741aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf("%-8s %-15s %s\n", "#Ifindex", "IP", "MAC"); 742aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (dbase->seq(dbase, &dbkey, &dbdat, R_NEXT) == 0) { 743ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger struct dbkey *key = dbkey.data; 744aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (handle_if(key->iface)) { 745aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!IS_NEG(dbdat.data)) { 746f332d169246447bd5e258ac03d5ee840a70adb1eshemminger char b1[18]; 747aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf("%-8d %-15s %s\n", 748aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger key->iface, 749aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger inet_ntoa(*(struct in_addr*)&key->addr), 750aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger hexstring_n2a(dbdat.data, 6, b1, 18)); 751aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 752aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf("%-8d %-15s FAILED: %dsec ago\n", 753aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger key->iface, 754aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger inet_ntoa(*(struct in_addr*)&key->addr), 755aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEG_AGE(dbdat.data)); 756aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 757aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 758aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 759aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 760aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 761aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_load || do_list) 762aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto out; 763aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 764aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[0].fd = socket(PF_PACKET, SOCK_DGRAM, 0); 765aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (pset[0].fd < 0) { 766aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("socket"); 767aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 768aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 769aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 770aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (1) { 771aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_ll sll; 772aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&sll, 0, sizeof(sll)); 773aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sll.sll_family = AF_PACKET; 774aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sll.sll_protocol = htons(ETH_P_ARP); 775aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sll.sll_ifindex = (ifnum == 1 ? ifvec[0] : 0); 776aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (bind(pset[0].fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) { 777aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("bind"); 778aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 779aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 780aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 781aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 782aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_open(&rth, RTMGRP_NEIGH) < 0) { 783aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("rtnl_open"); 784aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger goto do_abort; 785aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 786aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[1].fd = rth.fd; 787aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 788aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger load_initial_table(); 789aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 790a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger if (daemon(0, 0)) { 791a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger perror("arpd: daemon"); 792a7a9ddbb675b7fbd184c3ab40817265b0b207a23Mike Frysinger goto do_abort; 793aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 794aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 795aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger openlog("arpd", LOG_PID | LOG_CONS, LOG_DAEMON); 796aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger catch_signal(SIGINT, sig_exit); 797aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger catch_signal(SIGTERM, sig_exit); 798aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger catch_signal(SIGHUP, sig_sync); 799aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger catch_signal(SIGUSR1, sig_stats); 800aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 801aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define EVENTS (POLLIN|POLLPRI|POLLERR|POLLHUP) 802aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[0].events = EVENTS; 803aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[0].revents = 0; 804aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[1].events = EVENTS; 805aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger pset[1].revents = 0; 806aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 807aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger sigsetjmp(env, 1); 808aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 809aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (;;) { 810aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger in_poll = 1; 811aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 812aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_exit) 813aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 814aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_sync) { 815aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger in_poll = 0; 816aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->sync(dbase, 0); 817aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_sync = 0; 818aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger in_poll = 1; 819aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 820aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_stats) 821aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger send_stats(); 8220df7db3cf431d88953cda6220e76ece39bd0c344Stephen Hemminger if (poll(pset, 2, poll_timeout) > 0) { 823aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger in_poll = 0; 824aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (pset[0].revents&EVENTS) 825aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger get_arp_pkt(); 826aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (pset[1].revents&EVENTS) 827aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger get_kern_msg(); 828aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 829aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger do_sync = 1; 830aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 831aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 832aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 833aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger undo_sysctl_adjustments(); 834aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerout: 835aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->close(dbase); 836aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(0); 837aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 838aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerdo_abort: 839aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dbase->close(dbase); 840aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 841aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 842