ipneigh.c revision aba5acdfdb347d2c21fc67d613d83d4430ca3937
1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* 2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * ipneigh.c "ip neigh". 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 * Changes: 13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * 14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses 15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */ 16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h> 18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h> 19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h> 20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h> 21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h> 22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h> 23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/time.h> 24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <net/if.h> 25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h> 26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h> 27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/ip.h> 28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "rt_names.h" 30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h" 31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "ip_common.h" 32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY) 34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic struct 36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int family; 38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int index; 39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int state; 40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int unused_only; 41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger inet_prefix pfx; 42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int flushed; 43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *flushb; 44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int flushp; 45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int flushe; 46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtnl_handle *rth; 47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} filter; 48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) __attribute__((noreturn)); 50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) 52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Usage: ip neigh { add | del | change | replace } { ADDR [ lladdr LLADDR ]\n" 54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger " [ nud { permanent | noarp | stale | reachable } ]\n" 55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger " | proxy ADDR } [ dev DEV ]\n"); 56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " ip neigh {show|flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n"); 57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint nud_state_a2n(unsigned *state, char *arg) 61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(arg, "permanent") == 0) 63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *state = NUD_PERMANENT; 64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (matches(arg, "reachable") == 0) 65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *state = NUD_REACHABLE; 66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (strcmp(arg, "noarp") == 0) 67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *state = NUD_NOARP; 68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (strcmp(arg, "none") == 0) 69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *state = NUD_NONE; 70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (strcmp(arg, "stale") == 0) 71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *state = NUD_STALE; 72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (strcmp(arg, "incomplete") == 0) 73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *state = NUD_INCOMPLETE; 74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (strcmp(arg, "delay") == 0) 75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *state = NUD_DELAY; 76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (strcmp(arg, "probe") == 0) 77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *state = NUD_PROBE; 78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (matches(arg, "failed") == 0) 79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *state = NUD_FAILED; 80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else { 81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_unsigned(state, arg, 0)) 82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (*state>=0x100 || (*state&((*state)-1))) 84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerchar * nud_state_n2a(__u8 state, char *buf, int len) 90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger switch (state) { 92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case NUD_NONE: 93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return "none"; 94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case NUD_INCOMPLETE: 95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return "incomplete"; 96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case NUD_REACHABLE: 97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return "reachable"; 98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case NUD_STALE: 99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return "stale"; 100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case NUD_DELAY: 101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return "delay"; 102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case NUD_PROBE: 103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return "probe"; 104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case NUD_FAILED: 105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return "failed"; 106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case NUD_NOARP: 107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return "noarp"; 108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger case NUD_PERMANENT: 109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return "permanent"; 110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger default: 111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger snprintf(buf, len, "%x", state); 112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return buf; 113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int flush_update(void) 117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { 119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("Failed to send flush request\n"); 120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.flushp = 0; 123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int ipneigh_modify(int cmd, int flags, int argc, char **argv) 128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtnl_handle rth; 130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct { 131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct nlmsghdr n; 132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ndmsg ndm; 133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char buf[256]; 134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } req; 135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *d = NULL; 136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int dst_ok = 0; 137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int lladdr_ok = 0; 138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char * lla = NULL; 139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger inet_prefix dst; 140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&req, 0, sizeof(req)); 142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); 144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.n.nlmsg_flags = NLM_F_REQUEST|flags; 145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.n.nlmsg_type = cmd; 146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.ndm.ndm_family = preferred_family; 147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.ndm.ndm_state = NUD_PERMANENT; 148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "lladdr") == 0) { 151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (lladdr_ok) 153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("lladdr", *argv); 154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger lla = *argv; 155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger lladdr_ok = 1; 156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "nud") == 0) { 157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned state; 158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (nud_state_a2n(&state, *argv)) 160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg("nud state is bad", *argv); 161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.ndm.ndm_state = state; 162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "proxy") == 0) { 163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dst_ok) 167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("address", *argv); 168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger get_addr(&dst, *argv, preferred_family); 169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dst_ok = 1; 170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.ndm.ndm_flags |= NTF_PROXY; 171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "dev") == 0) { 172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger d = *argv; 174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "to") == 0) { 176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) { 179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dst_ok) 182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg2("to", *argv); 183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger get_addr(&dst, *argv, preferred_family); 184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dst_ok = 1; 185aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 186aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (d == NULL || !dst_ok || dst.family == AF_UNSPEC) { 189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Device and destination are required arguments.\n"); 190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.ndm.ndm_family = dst.family; 193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen); 194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (lla && strcmp(lla, "null")) { 196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u8 llabuf[16]; 197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int l; 198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger l = ll_addr_a2n(llabuf, sizeof(llabuf), lla); 200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(&req.n, sizeof(req), NDA_LLADDR, llabuf, l); 201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_open(&rth, 0) < 0) 204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ll_init_map(&rth); 207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((req.ndm.ndm_ifindex = ll_name_to_index(d)) == 0) { 209aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Cannot find device \"%s\"\n", d); 210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 212aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(2); 215aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(0); 217aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 218aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 219aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 220aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) 221aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 222aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger FILE *fp = (FILE*)arg; 223aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ndmsg *r = NLMSG_DATA(n); 224aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int len = n->nlmsg_len; 225aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtattr * tb[NDA_MAX+1]; 226aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char abuf[256]; 227aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 228aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) { 229aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n", 230aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); 231aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 232aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 233aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 234aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger len -= NLMSG_LENGTH(sizeof(*r)); 235aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (len < 0) { 236aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); 237aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 238aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 239aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter.flushb && n->nlmsg_type != RTM_NEWNEIGH) 241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 243aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter.family && filter.family != r->ndm_family) 244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 245aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter.index && filter.index != r->ndm_ifindex) 246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!(filter.state&r->ndm_state) && 248aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (r->ndm_state || !(filter.state&0x100)) && 249aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger (r->ndm_family != AF_DECnet)) 250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 251aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 252aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(tb, 0, sizeof(tb)); 253aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); 254aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 255aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (tb[NDA_DST]) { 256aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter.pfx.family) { 257aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger inet_prefix dst; 258aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&dst, 0, sizeof(dst)); 259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dst.family = r->ndm_family; 260aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memcpy(&dst.data, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); 261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) 262aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 264aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 265aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter.unused_only && tb[NDA_CACHEINFO]) { 266aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); 267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ci->ndm_refcnt) 268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 270aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter.flushb) { 272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct nlmsghdr *fn; 273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { 274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (flush_update()) 275aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 276aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 277aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); 278aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memcpy(fn, n, n->nlmsg_len); 279aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fn->nlmsg_type = RTM_DELNEIGH; 280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fn->nlmsg_flags = NLM_F_REQUEST; 281aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fn->nlmsg_seq = ++filter.rth->seq; 282aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; 283aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.flushed++; 284aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (show_stats < 2) 285aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 286aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 287aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 288aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (tb[NDA_DST]) { 289aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "%s ", 290aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger format_host(r->ndm_family, 291aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger RTA_PAYLOAD(tb[NDA_DST]), 292aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger RTA_DATA(tb[NDA_DST]), 293aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger abuf, sizeof(abuf))); 294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!filter.index && r->ndm_ifindex) 296aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex)); 297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (tb[NDA_LLADDR]) { 298aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b1); 299aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]), 300aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger RTA_PAYLOAD(tb[NDA_LLADDR]), 301aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ll_index_to_type(r->ndm_ifindex), 302aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger b1, sizeof(b1))); 303aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (r->ndm_flags & NTF_ROUTER) { 305aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, " router"); 306aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 307aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (tb[NDA_CACHEINFO] && show_stats) { 308aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger static int hz; 309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); 310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!hz) 311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger hz = get_hz(); 312aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ci->ndm_refcnt) 313aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf(" ref %d", ci->ndm_refcnt); 314aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz, 315aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ci->ndm_confirmed/hz, ci->ndm_updated/hz); 316aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 317aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 318aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (r->ndm_state) { 319aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b1); 320aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, " nud %s", nud_state_n2a(r->ndm_state, b1, sizeof(b1))); 321aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 322aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "\n"); 323aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 324aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fflush(fp); 325aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 326aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 327aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 328aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid ipneigh_reset_filter() 329aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 330aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&filter, 0, sizeof(filter)); 331aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.state = ~0; 332aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 333aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 334aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_show_or_flush(int argc, char **argv, int flush) 335aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 336aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *filter_dev = NULL; 337aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtnl_handle rth; 338aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int state_given = 0; 339aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 340aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ipneigh_reset_filter(); 341aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 342aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!filter.family) 343aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.family = preferred_family; 344aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 345aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (flush) { 346aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc <= 0) { 347aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Flush requires arguments.\n"); 348aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 349aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 350aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.state = ~(NUD_PERMANENT|NUD_NOARP); 351aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 352aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.state = 0xFF & ~NUD_NOARP; 353aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 354aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 355aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "dev") == 0) { 356aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 357aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter_dev) 358aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("dev", *argv); 359aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter_dev = *argv; 360aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "unused") == 0) { 361aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.unused_only = 1; 362aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "nud") == 0) { 363aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned state; 364aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 365aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!state_given) { 366aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger state_given = 1; 367aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.state = 0; 368aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 369aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (nud_state_a2n(&state, *argv)) { 370aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "all") != 0) 371aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg("nud state is bad", *argv); 372aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger state = ~0; 373aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (flush) 374aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger state &= ~NUD_NOARP; 375aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 376aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (state == 0) 377aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger state = 0x100; 378aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.state |= state; 379aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 380aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "to") == 0) { 381aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 382aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 383aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 384aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 385aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger get_prefix(&filter.pfx, *argv, filter.family); 386aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter.family == AF_UNSPEC) 387aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.family = filter.pfx.family; 388aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 389aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 390aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 391aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 392aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_open(&rth, 0) < 0) 393aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 394aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 395aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ll_init_map(&rth); 396aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 397aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter_dev) { 398aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((filter.index = ll_name_to_index(filter_dev)) == 0) { 399aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Cannot find device \"%s\"\n", filter_dev); 400aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 401aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 402aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 403aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 404aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (flush) { 405aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int round = 0; 406aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char flushb[4096-512]; 407aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 408aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.flushb = flushb; 409aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.flushp = 0; 410aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.flushe = sizeof(flushb); 411aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.rth = &rth; 412aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.state &= ~NUD_FAILED; 413aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 414aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger for (;;) { 415aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_wilddump_request(&rth, filter.family, RTM_GETNEIGH) < 0) { 416aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("Cannot send dump request"); 417aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 418aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 419aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter.flushed = 0; 420aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_dump_filter(&rth, print_neigh, stdout, NULL, NULL) < 0) { 421aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Flush terminated\n"); 422aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 423aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 424aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (filter.flushed == 0) { 425aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (round == 0) { 426aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Nothing to flush.\n"); 427aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (show_stats) 428aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":""); 429aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fflush(stdout); 430aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 431aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 432aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger round++; 433aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (flush_update() < 0) 434aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 435aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (show_stats) { 436aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf("\n*** Round %d, deleting %d entries ***\n", round, filter.flushed); 437aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fflush(stdout); 438aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 439aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 440aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 441aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 442aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_wilddump_request(&rth, filter.family, RTM_GETNEIGH) < 0) { 443aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("Cannot send dump request"); 444aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 445aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 446aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 447aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_dump_filter(&rth, print_neigh, stdout, NULL, NULL) < 0) { 448aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Dump terminated\n"); 449aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 450aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 451aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 452aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 453aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 454aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 455aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_ipneigh(int argc, char **argv) 456aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 457aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc > 0) { 458aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "add") == 0) 459aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipneigh_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1); 460aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "change") == 0 || 461aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "chg") == 0) 462aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipneigh_modify(RTM_NEWNEIGH, NLM_F_REPLACE, argc-1, argv+1); 463aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "replace") == 0) 464aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipneigh_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1); 465aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "delete") == 0) 466aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipneigh_modify(RTM_DELNEIGH, 0, argc-1, argv+1); 467aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "get") == 0) { 468aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Sorry, \"neigh get\" is not implemented :-(\n"); 469aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 470aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 471aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "show") == 0 || 472aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "lst") == 0 || 473aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "list") == 0) 474aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return do_show_or_flush(argc-1, argv+1, 0); 475aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "flush") == 0) 476aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return do_show_or_flush(argc-1, argv+1, 1); 477aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 478aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 479aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 480aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return do_show_or_flush(0, NULL, 0); 481aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 482aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Command \"%s\" is unknown, try \"ip neigh help\".\n", *argv); 483aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 484aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 485