1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * ipaddress.c "ip address". 3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can redistribute it and/or 5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * modify it under the terms of the GNU General Public License 6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as published by the Free Software Foundation; either version 7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2 of the License, or (at your option) any later version. 8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h> 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h> 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h> 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <syslog.h> 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fcntl.h> 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/ioctl.h> 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/ioctl.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/errno.h> 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h> 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fnmatch.h> 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/netdevice.h> 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if_arp.h> 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/sockios.h> 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "rt_names.h" 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "ll_map.h" 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "ip_common.h" 35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define MAX_ROUNDS 10 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct 39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int ifindex; 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int family; 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int oneline; 43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int showqueue; 44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix pfx; 45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int scope, scopemask; 46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int flags, flagmask; 47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int up; 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *label; 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int flushed; 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *flushb; 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int flushp; 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int flushe; 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} filter; 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int do_link; 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void usage(void) __attribute__((noreturn)); 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void usage(void) 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (do_link) { 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iplink_usage(); 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n"); 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ CONFFLAG-LIST]\n"); 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " ip addr del IFADDR dev STRING\n"); 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n"); 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n"); 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n"); 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ broadcast ADDR ] [ anycast ADDR ]\n"); 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ label STRING ] [ scope SCOPE-ID ]\n"); 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n"); 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "FLAG := [ permanent | dynamic | secondary | primary |\n"); 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " tentative | deprecated | CONFFLAG-LIST ]\n"); 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n"); 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CONFFLAG := [ home | nodad ]\n"); 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n"); 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "LFT := forever | SECONDS\n"); 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid print_link_flags(FILE *fp, unsigned flags, unsigned mdown) 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "<"); 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flags & IFF_UP && !(flags & IFF_RUNNING)) 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "NO-CARRIER%s", flags ? "," : ""); 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat flags &= ~IFF_RUNNING; 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define _PF(f) if (flags&IFF_##f) { \ 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat flags &= ~IFF_##f ; \ 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, #f "%s", flags ? "," : ""); } 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(LOOPBACK); 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(BROADCAST); 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(POINTOPOINT); 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(MULTICAST); 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(NOARP); 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(ALLMULTI); 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(PROMISC); 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(MASTER); 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(SLAVE); 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(DEBUG); 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(DYNAMIC); 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(AUTOMEDIA); 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(PORTSEL); 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(NOTRAILERS); 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(UP); 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(LOWER_UP); 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(DORMANT); 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(ECHO); 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#undef _PF 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flags) 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%x", flags); 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (mdown) 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, ",M-DOWN"); 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "> "); 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *oper_states[] = { 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN", 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "TESTING", "DORMANT", "UP" 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_operstate(FILE *f, __u8 state) 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (state >= sizeof(oper_states)/sizeof(oper_states[0])) 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "state %#x ", state); 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "state %s ", oper_states[state]); 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_queuelen(FILE *f, const char *name) 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifreq ifr; 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int s; 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s = socket(AF_INET, SOCK_STREAM, 0); 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (s < 0) 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return; 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&ifr, 0, sizeof(ifr)); 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcpy(ifr.ifr_name, name); 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) { 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "ioctl(SIOCGIFXQLEN) failed: %s\n", strerror(errno)); 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat close(s); 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return; 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat close(s); 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifr.ifr_qlen) 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "qlen %d", ifr.ifr_qlen); 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_linktype(FILE *fp, struct rtattr *tb) 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *linkinfo[IFLA_INFO_MAX+1]; 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct link_util *lu; 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *kind; 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb); 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!linkinfo[IFLA_INFO_KIND]) 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return; 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]); 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %s ", kind); 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lu = get_link_kind(kind); 170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!lu || !lu->print_opt) 171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return; 172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (1) { 174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *attr[lu->maxattr+1], **data = NULL; 175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (linkinfo[IFLA_INFO_DATA]) { 177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(attr, lu->maxattr, 178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat linkinfo[IFLA_INFO_DATA]); 179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat data = attr; 180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lu->print_opt(lu, fp, data); 182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (linkinfo[IFLA_INFO_XSTATS] && show_stats && 184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lu->print_xstats) 185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lu->print_xstats(lu, fp, linkinfo[IFLA_INFO_XSTATS]); 186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_linkinfo(const struct sockaddr_nl *who, 190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr *n, void *arg) 191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat FILE *fp = (FILE*)arg; 193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifinfomsg *ifi = NLMSG_DATA(n); 194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr * tb[IFLA_MAX+1]; 195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int len = n->nlmsg_len; 196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned m_flag = 0; 197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) 199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 201dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len -= NLMSG_LENGTH(sizeof(*ifi)); 202dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len < 0) 203dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 204dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 205dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.ifindex && ifi->ifi_index != filter.ifindex) 206dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 207dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.up && !(ifi->ifi_flags&IFF_UP)) 208dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 209dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 210dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); 211dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_IFNAME] == NULL) { 212dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index); 213dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 214dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.label && 215dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (!filter.family || filter.family == AF_PACKET) && 216dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) 217dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 218dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 219dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type == RTM_DELLINK) 220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "Deleted "); 221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%d: %s", ifi->ifi_index, 223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>"); 224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_LINK]) { 226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); 228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (iflink == 0) 229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "@NONE: "); 230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1)); 232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m_flag = ll_index_to_flags(iflink); 233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m_flag = !(m_flag & IFF_UP); 234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, ": "); 237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_link_flags(fp, ifi->ifi_flags, m_flag); 239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_MTU]) 241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); 242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_QDISC]) 243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); 244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifdef IFLA_MASTER 245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_MASTER]) { 246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); 248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_OPERSTATE]) 251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE])); 252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.showqueue) 254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_queuelen(fp, (char*)RTA_DATA(tb[IFLA_IFNAME])); 255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!filter.family || filter.family == AF_PACKET) { 257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); 260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_ADDRESS]) { 262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), 263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(tb[IFLA_ADDRESS]), 264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifi->ifi_type, 265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat b1, sizeof(b1))); 266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_BROADCAST]) { 268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifi->ifi_flags&IFF_POINTOPOINT) 269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " peer "); 270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " brd "); 272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), 273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(tb[IFLA_BROADCAST]), 274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifi->ifi_type, 275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat b1, sizeof(b1))); 276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (do_link && tb[IFLA_LINKINFO] && show_details) 280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_linktype(fp, tb[IFLA_LINKINFO]); 281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (do_link && tb[IFLA_IFALIAS]) 283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp,"\n alias %s", 284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (const char *) RTA_DATA(tb[IFLA_IFALIAS])); 285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (do_link && tb[IFLA_STATS] && show_stats) { 287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtnl_link_stats slocal; 288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtnl_link_stats *s = RTA_DATA(tb[IFLA_STATS]); 289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (((unsigned long)s) & (sizeof(unsigned long)-1)) { 290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(&slocal, s, sizeof(slocal)); 291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s = &slocal; 292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", 295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_compressed ? "compressed" : "", _SL_); 296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", 297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_bytes, s->rx_packets, s->rx_errors, 298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_dropped, s->rx_over_errors, 299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->multicast 300dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ); 301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (s->rx_compressed) 302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-7u", s->rx_compressed); 303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats > 1) { 304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); 306dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-7u %-7u %-7u %-7u %-7u", 307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_length_errors, 308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_crc_errors, 309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_frame_errors, 310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_fifo_errors, 311dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_missed_errors 312dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ); 313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", 316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_compressed ? "compressed" : "", _SL_); 317dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", 318dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_bytes, s->tx_packets, s->tx_errors, 319dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_dropped, s->tx_carrier_errors, s->collisions); 320dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (s->tx_compressed) 321dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-7u", s->tx_compressed); 322dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats > 1) { 323dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 324dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " TX errors: aborted fifo window heartbeat%s", _SL_); 325dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-7u %-7u %-7u %-7u", 326dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_aborted_errors, 327dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_fifo_errors, 328dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_window_errors, 329dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_heartbeat_errors 330dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ); 331dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 332dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 333dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "\n"); 334dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(fp); 335dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 336dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 337dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 338dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int flush_update(void) 339dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 340dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_send_check(&rth, filter.flushb, filter.flushp) < 0) { 341dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("Failed to send flush request"); 342dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 343dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 344dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushp = 0; 345dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 346dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 347dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 348dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int set_lifetime(unsigned int *lifetime, char *argv) 349dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 350dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(argv, "forever") == 0) 351dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *lifetime = INFINITY_LIFE_TIME; 352dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (get_u32(lifetime, argv, 0)) 353dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 354dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 355dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 356dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 357dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 358dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, 359dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *arg) 360dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 361dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat FILE *fp = (FILE*)arg; 362dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 363dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int len = n->nlmsg_len; 364dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int deprecated = 0; 365dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr * rta_tb[IFA_MAX+1]; 366dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char abuf[256]; 367dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 368dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 369dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) 370dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 371dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len -= NLMSG_LENGTH(sizeof(*ifa)); 372dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len < 0) { 373dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); 374dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 375dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 376dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 377dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.flushb && n->nlmsg_type != RTM_NEWADDR) 378dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 379dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 380dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); 381dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 382dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!rta_tb[IFA_LOCAL]) 383dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; 384dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!rta_tb[IFA_ADDRESS]) 385dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL]; 386dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 387dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.ifindex && filter.ifindex != ifa->ifa_index) 388dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 389dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((filter.scope^ifa->ifa_scope)&filter.scopemask) 390dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 391dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((filter.flags^ifa->ifa_flags)&filter.flagmask) 392dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 393dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.label) { 394dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 395dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const char *label; 396dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_LABEL]) 397dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat label = RTA_DATA(rta_tb[IFA_LABEL]); 398dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 399dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat label = ll_idx_n2a(ifa->ifa_index, b1); 400dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fnmatch(filter.label, label, 0) != 0) 401dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 402dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 403dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.pfx.family) { 404dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_LOCAL]) { 405dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix dst; 406dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&dst, 0, sizeof(dst)); 407dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst.family = ifa->ifa_family; 408dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL])); 409dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) 410dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 411dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 412dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 413dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 414dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family && filter.family != ifa->ifa_family) 415dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 416dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 417dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.flushb) { 418dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr *fn; 419dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { 420dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flush_update()) 421dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 422dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 423dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); 424dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(fn, n, n->nlmsg_len); 425dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fn->nlmsg_type = RTM_DELADDR; 426dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fn->nlmsg_flags = NLM_F_REQUEST; 427dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fn->nlmsg_seq = ++rth.seq; 428dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; 429dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushed++; 430dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats < 2) 431dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 432dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 433dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 434dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type == RTM_DELADDR) 435dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "Deleted "); 436dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 437dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.oneline || filter.flushb) 438dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); 439dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_family == AF_INET) 440dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " inet "); 441dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (ifa->ifa_family == AF_INET6) 442dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " inet6 "); 443dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (ifa->ifa_family == AF_DECnet) 444dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " dnet "); 445dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (ifa->ifa_family == AF_IPX) 446dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " ipx "); 447dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 448dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " family %d ", ifa->ifa_family); 449dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 450dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_LOCAL]) { 451dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", rt_addr_n2a(ifa->ifa_family, 452dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(rta_tb[IFA_LOCAL]), 453dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_DATA(rta_tb[IFA_LOCAL]), 454dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat abuf, sizeof(abuf))); 455dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 456dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_ADDRESS] == NULL || 457dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0) { 458dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "/%d ", ifa->ifa_prefixlen); 459dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 460dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " peer %s/%d ", 461dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rt_addr_n2a(ifa->ifa_family, 462dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(rta_tb[IFA_ADDRESS]), 463dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_DATA(rta_tb[IFA_ADDRESS]), 464dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat abuf, sizeof(abuf)), 465dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_prefixlen); 466dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 467dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 468dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 469dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_BROADCAST]) { 470dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "brd %s ", 471dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rt_addr_n2a(ifa->ifa_family, 472dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(rta_tb[IFA_BROADCAST]), 473dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_DATA(rta_tb[IFA_BROADCAST]), 474dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat abuf, sizeof(abuf))); 475dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 476dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_ANYCAST]) { 477dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "any %s ", 478dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rt_addr_n2a(ifa->ifa_family, 479dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(rta_tb[IFA_ANYCAST]), 480dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_DATA(rta_tb[IFA_ANYCAST]), 481dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat abuf, sizeof(abuf))); 482dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 483dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1))); 484dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_SECONDARY) { 485dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_SECONDARY; 486dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "secondary "); 487dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 488dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_TENTATIVE) { 489dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_TENTATIVE; 490dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "tentative "); 491dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 492dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_DEPRECATED) { 493dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_DEPRECATED; 494dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat deprecated = 1; 495dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "deprecated "); 496dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 497dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_HOMEADDRESS) { 498dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_HOMEADDRESS; 499dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "home "); 500dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 501dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_NODAD) { 502dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_NODAD; 503dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "nodad "); 504dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 505dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!(ifa->ifa_flags&IFA_F_PERMANENT)) { 506dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "dynamic "); 507dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else 508dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_PERMANENT; 509dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_DADFAILED) { 510dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_DADFAILED; 511dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "dadfailed "); 512dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 513dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags) 514dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "flags %02x ", ifa->ifa_flags); 515dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_LABEL]) 516dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", (char*)RTA_DATA(rta_tb[IFA_LABEL])); 517dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_CACHEINFO]) { 518dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]); 519dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[128]; 520dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 521dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ci->ifa_valid == INFINITY_LIFE_TIME) 522dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf, "valid_lft forever"); 523dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 524dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf, "valid_lft %usec", ci->ifa_valid); 525dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ci->ifa_prefered == INFINITY_LIFE_TIME) 526dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf+strlen(buf), " preferred_lft forever"); 527dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 528dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (deprecated) 529dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf+strlen(buf), " preferred_lft %dsec", 530dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ci->ifa_prefered); 531dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 532dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf+strlen(buf), " preferred_lft %usec", 533dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ci->ifa_prefered); 534dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 535dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %s", buf); 536dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 537dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "\n"); 538dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(fp); 539dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 540dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 541dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 542dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_addrinfo_primary(const struct sockaddr_nl *who, struct nlmsghdr *n, 543dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *arg) 544dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 545dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 546dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 547dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ifa->ifa_flags & IFA_F_SECONDARY) 548dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 549dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 550dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return print_addrinfo(who, n, arg); 551dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 552dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 553dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_addrinfo_secondary(const struct sockaddr_nl *who, struct nlmsghdr *n, 554dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *arg) 555dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 556dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 557dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 558dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags & IFA_F_SECONDARY) 559dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 560dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 561dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return print_addrinfo(who, n, arg); 562dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 563dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 564dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct nlmsg_list 565dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 566dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *next; 567dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr h; 568dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 569dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 570dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp) 571dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 572dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for ( ;ainfo ; ainfo = ainfo->next) { 573dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr *n = &ainfo->h; 574dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 575dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 576dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type != RTM_NEWADDR) 577dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 578dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 579dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa))) 580dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 581dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 582dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_index != ifindex || 583dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (filter.family && filter.family != ifa->ifa_family)) 584dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 585dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 586dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_addrinfo(NULL, n, fp); 587dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 588dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 589dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 590dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 591dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 592dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, 593dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *arg) 594dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 595dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list **linfo = (struct nlmsg_list**)arg; 596dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *h; 597dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list **lp; 598dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 599dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat h = malloc(n->nlmsg_len+sizeof(void*)); 600dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (h == NULL) 601dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 602dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 603dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(&h->h, n, n->nlmsg_len); 604dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat h->next = NULL; 605dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 606dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */; 607dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *lp = h; 608dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 609dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ll_remember_index(who, n, NULL); 610dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 611dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 612dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 613dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int ipaddr_list_or_flush(int argc, char **argv, int flush) 614dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 615dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *linfo = NULL; 616dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *ainfo = NULL; 617dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *l, *n; 618dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *filter_dev = NULL; 619dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int no_link = 0; 620dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 621dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ipaddr_reset_filter(oneline); 622dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.showqueue = 1; 623dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 624dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family == AF_UNSPEC) 625dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.family = preferred_family; 626dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 627dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flush) { 628dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc <= 0) { 629dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Flush requires arguments.\n"); 630dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 631dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 632dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family == AF_PACKET) { 633dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Cannot flush link addresses.\n"); 634dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 635dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 636dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 637dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 638dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 639dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "to") == 0) { 640dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 641dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_prefix(&filter.pfx, *argv, filter.family); 642dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family == AF_UNSPEC) 643dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.family = filter.pfx.family; 644dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "scope") == 0) { 645dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned scope = 0; 646dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 647dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.scopemask = -1; 648dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_rtscope_a2n(&scope, *argv)) { 649dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "all") != 0) 650dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("invalid \"scope\"\n", *argv); 651dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat scope = RT_SCOPE_NOWHERE; 652dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.scopemask = 0; 653dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 654dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.scope = scope; 655dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "up") == 0) { 656dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.up = 1; 657dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "dynamic") == 0) { 658dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags &= ~IFA_F_PERMANENT; 659dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_PERMANENT; 660dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "permanent") == 0) { 661dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_PERMANENT; 662dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_PERMANENT; 663dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "secondary") == 0) { 664dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_SECONDARY; 665dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_SECONDARY; 666dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "primary") == 0) { 667dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags &= ~IFA_F_SECONDARY; 668dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_SECONDARY; 669dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "tentative") == 0) { 670dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_TENTATIVE; 671dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_TENTATIVE; 672dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "deprecated") == 0) { 673dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_DEPRECATED; 674dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_DEPRECATED; 675dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "home") == 0) { 676dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_HOMEADDRESS; 677dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_HOMEADDRESS; 678dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "nodad") == 0) { 679dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_NODAD; 680dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_NODAD; 681dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "label") == 0) { 682dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 683dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.label = *argv; 684dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 685dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "dev") == 0) { 686dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 687dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 688dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "help") == 0) 689dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 690dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter_dev) 691dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg2("dev", *argv); 692dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter_dev = *argv; 693dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 694dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argv++; argc--; 695dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 696dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 697dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) { 698dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("Cannot send dump request"); 699dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 700dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 701dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 702dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) { 703dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Dump terminated\n"); 704dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 705dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 706dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 707dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter_dev) { 708dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.ifindex = ll_name_to_index(filter_dev); 709dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.ifindex <= 0) { 710dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Device \"%s\" does not exist.\n", filter_dev); 711dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 712dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 713dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 714dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 715dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flush) { 716dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int round = 0; 717dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char flushb[4096-512]; 718dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 719dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushb = flushb; 720dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushp = 0; 721dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushe = sizeof(flushb); 722dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 723dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (round < MAX_ROUNDS) { 724dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const struct rtnl_dump_filter_arg a[3] = { 725dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 726dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .filter = print_addrinfo_secondary, 727dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg1 = stdout, 728dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .junk = NULL, 729dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg2 = NULL 730dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat }, 731dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 732dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .filter = print_addrinfo_primary, 733dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg1 = stdout, 734dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .junk = NULL, 735dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg2 = NULL 736dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat }, 737dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 738dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .filter = NULL, 739dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg1 = NULL, 740dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .junk = NULL, 741dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg2 = NULL 742dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat }, 743dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat }; 744dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 745dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("Cannot send dump request"); 746dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 747dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 748dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushed = 0; 749dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_dump_filter_l(&rth, a) < 0) { 750dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Flush terminated\n"); 751dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 752dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 753dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.flushed == 0) { 754dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats) { 755dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (round == 0) 756dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("Nothing to flush.\n"); 757dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 758dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":""); 759dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 760dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(stdout); 761dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 762dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 763dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat round++; 764dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flush_update() < 0) 765dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 1; 766dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 767dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats) { 768dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed); 769dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(stdout); 770dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 771dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 772dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "*** Flush remains incomplete after %d rounds. ***\n", MAX_ROUNDS); fflush(stderr); 773dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 1; 774dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 775dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 776dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family != AF_PACKET) { 777dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 778dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("Cannot send dump request"); 779dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 780dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 781dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 782dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) { 783dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Dump terminated\n"); 784dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 785dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 786dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 787dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 788dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 789dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family && filter.family != AF_PACKET) { 790dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list **lp; 791dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lp=&linfo; 792dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 793dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.oneline) 794dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat no_link = 1; 795dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 796dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while ((l=*lp)!=NULL) { 797dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int ok = 0; 798dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 799dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *a; 800dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 801dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (a=ainfo; a; a=a->next) { 802dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr *n = &a->h; 803dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 804dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 805dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_index != ifi->ifi_index || 806dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (filter.family && filter.family != ifa->ifa_family)) 807dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 808dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((filter.scope^ifa->ifa_scope)&filter.scopemask) 809dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 810dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((filter.flags^ifa->ifa_flags)&filter.flagmask) 811dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 812dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.pfx.family || filter.label) { 813dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tb[IFA_MAX+1]; 814dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n)); 815dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!tb[IFA_LOCAL]) 816dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tb[IFA_LOCAL] = tb[IFA_ADDRESS]; 817dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 818dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.pfx.family && tb[IFA_LOCAL]) { 819dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix dst; 820dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&dst, 0, sizeof(dst)); 821dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst.family = ifa->ifa_family; 822dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL])); 823dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) 824dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 825dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 826dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.label) { 827dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 828dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const char *label; 829dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFA_LABEL]) 830dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat label = RTA_DATA(tb[IFA_LABEL]); 831dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 832dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat label = ll_idx_n2a(ifa->ifa_index, b1); 833dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fnmatch(filter.label, label, 0) != 0) 834dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 835dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 836dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 837dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 838dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ok = 1; 839dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 840dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 841dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ok) 842dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *lp = l->next; 843dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 844dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lp = &l->next; 845dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 846dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 847dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 848dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (l=linfo; l; l = n) { 849dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat n = l->next; 850dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) { 851dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 852dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family != AF_PACKET) 853dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_selected_addrinfo(ifi->ifi_index, ainfo, stdout); 854dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 855dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(stdout); 856dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(l); 857dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 858dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 859dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 860dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 861dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 862dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint ipaddr_list_link(int argc, char **argv) 863dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 864dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat preferred_family = AF_PACKET; 865dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat do_link = 1; 866dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_list_or_flush(argc, argv, 0); 867dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 868dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 869dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid ipaddr_reset_filter(int oneline) 870dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 871dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&filter, 0, sizeof(filter)); 872dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.oneline = oneline; 873dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 874dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 875dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int default_scope(inet_prefix *lcl) 876dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 877dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lcl->family == AF_INET) { 878dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127) 879dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return RT_SCOPE_HOST; 880dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 881dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 882dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 883dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 884dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int ipaddr_modify(int cmd, int flags, int argc, char **argv) 885dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 886dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct { 887dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr n; 888dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg ifa; 889dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[256]; 890dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } req; 891dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *d = NULL; 892dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *l = NULL; 893dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *lcl_arg = NULL; 894dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *valid_lftp = NULL; 895dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *preferred_lftp = NULL; 896dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix lcl; 897dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix peer; 898dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int local_len = 0; 899dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int peer_len = 0; 900dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int brd_len = 0; 901dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int any_len = 0; 902dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int scoped = 0; 903dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 preferred_lft = INFINITY_LIFE_TIME; 904dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 valid_lft = INFINITY_LIFE_TIME; 905dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifa_cacheinfo cinfo; 906dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 907dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&req, 0, sizeof(req)); 908dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 909dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); 910dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.n.nlmsg_flags = NLM_F_REQUEST | flags; 911dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.n.nlmsg_type = cmd; 912dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = preferred_family; 913dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 914dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 915dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "peer") == 0 || 916dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "remote") == 0) { 917dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 918dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 919dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (peer_len) 920dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("peer", *argv); 921dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_prefix(&peer, *argv, req.ifa.ifa_family); 922dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat peer_len = peer.bytelen; 923dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family == AF_UNSPEC) 924dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = peer.family; 925dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen); 926dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_prefixlen = peer.bitlen; 927dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "broadcast") == 0 || 928dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "brd") == 0) { 929dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix addr; 930dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 931dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (brd_len) 932dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("broadcast", *argv); 933dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "+") == 0) 934dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd_len = -1; 935dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (strcmp(*argv, "-") == 0) 936dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd_len = -2; 937dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 938dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_addr(&addr, *argv, req.ifa.ifa_family); 939dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family == AF_UNSPEC) 940dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = addr.family; 941dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen); 942dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd_len = addr.bytelen; 943dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 944dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "anycast") == 0) { 945dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix addr; 946dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 947dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (any_len) 948dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("anycast", *argv); 949dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_addr(&addr, *argv, req.ifa.ifa_family); 950dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family == AF_UNSPEC) 951dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = addr.family; 952dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); 953dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat any_len = addr.bytelen; 954dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "scope") == 0) { 955dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned scope = 0; 956dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 957dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_rtscope_a2n(&scope, *argv)) 958dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg(*argv, "invalid scope value."); 959dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_scope = scope; 960dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat scoped = 1; 961dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "dev") == 0) { 962dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 963dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat d = *argv; 964dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "label") == 0) { 965dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 966dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat l = *argv; 967dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1); 968dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "valid_lft") == 0) { 969dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (valid_lftp) 970dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("valid_lft", *argv); 971dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 972dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat valid_lftp = *argv; 973dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (set_lifetime(&valid_lft, *argv)) 974dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("valid_lft value", *argv); 975dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "preferred_lft") == 0) { 976dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (preferred_lftp) 977dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("preferred_lft", *argv); 978dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 979dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat preferred_lftp = *argv; 980dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (set_lifetime(&preferred_lft, *argv)) 981dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("preferred_lft value", *argv); 982dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "home") == 0) { 983dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_flags |= IFA_F_HOMEADDRESS; 984dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "nodad") == 0) { 985dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_flags |= IFA_F_NODAD; 986dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 987dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "local") == 0) { 988dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 989dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 990dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "help") == 0) 991dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 992dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (local_len) 993dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg2("local", *argv); 994dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lcl_arg = *argv; 995dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_prefix(&lcl, *argv, req.ifa.ifa_family); 996dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family == AF_UNSPEC) 997dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = lcl.family; 998dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); 999dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat local_len = lcl.bytelen; 1000dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1001dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 1002dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1003dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (d == NULL) { 1004dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Not enough information: \"dev\" argument is required.\n"); 1005dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1006dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1007dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (l && matches(d, l) != 0) { 1008dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l); 1009dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 1010dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1011dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1012dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (peer_len == 0 && local_len) { 1013dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) { 1014dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, 1015dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \ 1016dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \ 1017dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat " This special behaviour is likely to disappear in further releases,\n" \ 1018dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat " fix your scripts!\n", lcl_arg, local_len*8); 1019dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 1020dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat peer = lcl; 1021dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen); 1022dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1023dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1024dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_prefixlen == 0) 1025dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_prefixlen = lcl.bitlen; 1026dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1027dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (brd_len < 0 && cmd != RTM_DELADDR) { 1028dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix brd; 1029dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 1030dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family != AF_INET) { 1031dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Broadcast can be set only for IPv4 addresses\n"); 1032dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1033dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1034dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd = peer; 1035dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (brd.bitlen <= 30) { 1036dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i=31; i>=brd.bitlen; i--) { 1037dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (brd_len == -1) 1038dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd.data[0] |= htonl(1<<(31-i)); 1039dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 1040dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd.data[0] &= ~htonl(1<<(31-i)); 1041dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1042dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen); 1043dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd_len = brd.bytelen; 1044dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1045dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1046dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!scoped && cmd != RTM_DELADDR) 1047dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_scope = default_scope(&lcl); 1048dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1049dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ll_init_map(&rth); 1050dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1051dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) { 1052dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Cannot find device \"%s\"\n", d); 1053dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1054dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1055dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1056dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (valid_lftp || preferred_lftp) { 1057dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!valid_lft) { 1058dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "valid_lft is zero\n"); 1059dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1060dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1061dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (valid_lft < preferred_lft) { 1062dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "preferred_lft is greater than valid_lft\n"); 1063dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1064dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1065dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1066dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&cinfo, 0, sizeof(cinfo)); 1067dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cinfo.ifa_prefered = preferred_lft; 1068dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cinfo.ifa_valid = valid_lft; 1069dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo, 1070dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sizeof(cinfo)); 1071dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1072dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1073dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 1074dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(2); 1075dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1076dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 1077dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 1078dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1079dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint do_ipaddr(int argc, char **argv) 1080dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 1081dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc < 1) 1082dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_list_or_flush(0, NULL, 0); 1083dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "add") == 0) 1084dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1); 1085dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "change") == 0 || 1086dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "chg") == 0) 1087dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_modify(RTM_NEWADDR, NLM_F_REPLACE, argc-1, argv+1); 1088dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "replace") == 0) 1089dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1); 1090dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "delete") == 0) 1091dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_modify(RTM_DELADDR, 0, argc-1, argv+1); 1092dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 1093dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat || matches(*argv, "lst") == 0) 1094dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_list_or_flush(argc-1, argv+1, 0); 1095dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "flush") == 0) 1096dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_list_or_flush(argc-1, argv+1, 1); 1097dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "help") == 0) 1098dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 1099dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv); 1100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 1101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 1102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1103