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