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"); 651a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 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"); 751a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr, " tentative | deprecated | dadfailed | temporary |\n"); 761a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr, " CONFFLAG-LIST ]\n"); 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n"); 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "CONFFLAG := [ home | nodad ]\n"); 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n"); 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "LFT := forever | SECONDS\n"); 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid print_link_flags(FILE *fp, unsigned flags, unsigned mdown) 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "<"); 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flags & IFF_UP && !(flags & IFF_RUNNING)) 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "NO-CARRIER%s", flags ? "," : ""); 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat flags &= ~IFF_RUNNING; 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#define _PF(f) if (flags&IFF_##f) { \ 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat flags &= ~IFF_##f ; \ 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, #f "%s", flags ? "," : ""); } 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(LOOPBACK); 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(BROADCAST); 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(POINTOPOINT); 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(MULTICAST); 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(NOARP); 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(ALLMULTI); 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(PROMISC); 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(MASTER); 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(SLAVE); 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(DEBUG); 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(DYNAMIC); 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(AUTOMEDIA); 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(PORTSEL); 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(NOTRAILERS); 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(UP); 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(LOWER_UP); 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(DORMANT); 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat _PF(ECHO); 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#undef _PF 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flags) 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%x", flags); 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (mdown) 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, ",M-DOWN"); 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "> "); 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic const char *oper_states[] = { 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN", 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "TESTING", "DORMANT", "UP" 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_operstate(FILE *f, __u8 state) 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (state >= sizeof(oper_states)/sizeof(oper_states[0])) 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "state %#x ", state); 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "state %s ", oper_states[state]); 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_queuelen(FILE *f, const char *name) 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifreq ifr; 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int s; 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s = socket(AF_INET, SOCK_STREAM, 0); 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (s < 0) 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return; 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&ifr, 0, sizeof(ifr)); 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcpy(ifr.ifr_name, name); 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) { 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "ioctl(SIOCGIFXQLEN) failed: %s\n", strerror(errno)); 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat close(s); 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return; 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat close(s); 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifr.ifr_qlen) 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "qlen %d", ifr.ifr_qlen); 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void print_linktype(FILE *fp, struct rtattr *tb) 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *linkinfo[IFLA_INFO_MAX+1]; 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct link_util *lu; 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *kind; 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb); 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!linkinfo[IFLA_INFO_KIND]) 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return; 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]); 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %s ", kind); 169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lu = get_link_kind(kind); 171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!lu || !lu->print_opt) 172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return; 173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (1) { 175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *attr[lu->maxattr+1], **data = NULL; 176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (linkinfo[IFLA_INFO_DATA]) { 178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(attr, lu->maxattr, 179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat linkinfo[IFLA_INFO_DATA]); 180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat data = attr; 181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lu->print_opt(lu, fp, data); 183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (linkinfo[IFLA_INFO_XSTATS] && show_stats && 185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lu->print_xstats) 186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lu->print_xstats(lu, fp, linkinfo[IFLA_INFO_XSTATS]); 187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1901a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidtstatic void print_vfinfo(FILE *fp, struct rtattr *vfinfo) 1911a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt{ 1921a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct ifla_vf_mac *vf_mac; 1931a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct ifla_vf_vlan *vf_vlan; 1941a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct ifla_vf_tx_rate *vf_tx_rate; 1951a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct rtattr *vf[IFLA_VF_MAX+1]; 1961a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt SPRINT_BUF(b1); 1971a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 1981a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (vfinfo->rta_type != IFLA_VF_INFO) { 1991a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type); 2001a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return; 2011a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 2021a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 2031a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo); 2041a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 2051a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt vf_mac = RTA_DATA(vf[IFLA_VF_MAC]); 2061a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]); 2071a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]); 2081a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 2091a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, "\n vf %d MAC %s", vf_mac->vf, 2101a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt ll_addr_n2a((unsigned char *)&vf_mac->mac, 2111a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt ETH_ALEN, 0, b1, sizeof(b1))); 2121a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (vf_vlan->vlan) 2131a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, ", vlan %d", vf_vlan->vlan); 2141a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (vf_vlan->qos) 2151a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, ", qos %d", vf_vlan->qos); 2161a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (vf_tx_rate->rate) 2171a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate); 2181a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt} 2191a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_linkinfo(const struct sockaddr_nl *who, 221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr *n, void *arg) 222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat FILE *fp = (FILE*)arg; 224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifinfomsg *ifi = NLMSG_DATA(n); 225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr * tb[IFLA_MAX+1]; 226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int len = n->nlmsg_len; 227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned m_flag = 0; 228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) 230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len -= NLMSG_LENGTH(sizeof(*ifi)); 233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len < 0) 234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.ifindex && ifi->ifi_index != filter.ifindex) 237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.up && !(ifi->ifi_flags&IFF_UP)) 239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); 242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_IFNAME] == NULL) { 243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index); 244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.label && 246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (!filter.family || filter.family == AF_PACKET) && 247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) 248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type == RTM_DELLINK) 251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "Deleted "); 252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%d: %s", ifi->ifi_index, 254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>"); 255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_LINK]) { 257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); 259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (iflink == 0) 260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "@NONE: "); 261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1)); 263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m_flag = ll_index_to_flags(iflink); 264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat m_flag = !(m_flag & IFF_UP); 265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, ": "); 268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_link_flags(fp, ifi->ifi_flags, m_flag); 270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_MTU]) 272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); 273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_QDISC]) 274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); 275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#ifdef IFLA_MASTER 276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_MASTER]) { 277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); 279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#endif 281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_OPERSTATE]) 282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE])); 283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.showqueue) 285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_queuelen(fp, (char*)RTA_DATA(tb[IFLA_IFNAME])); 286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!filter.family || filter.family == AF_PACKET) { 288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); 291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_ADDRESS]) { 293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), 294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(tb[IFLA_ADDRESS]), 295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifi->ifi_type, 296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat b1, sizeof(b1))); 297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_BROADCAST]) { 299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifi->ifi_flags&IFF_POINTOPOINT) 300dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " peer "); 301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " brd "); 303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), 304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(tb[IFLA_BROADCAST]), 305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifi->ifi_type, 306dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat b1, sizeof(b1))); 307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (do_link && tb[IFLA_LINKINFO] && show_details) 311dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_linktype(fp, tb[IFLA_LINKINFO]); 312dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (do_link && tb[IFLA_IFALIAS]) 314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp,"\n alias %s", 315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (const char *) RTA_DATA(tb[IFLA_IFALIAS])); 316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 3171a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (do_link && tb[IFLA_STATS64] && show_stats) { 3181a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct rtnl_link_stats64 slocal; 3191a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct rtnl_link_stats64 *s = RTA_DATA(tb[IFLA_STATS64]); 3201a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (((unsigned long)s) & (sizeof(unsigned long)-1)) { 3211a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt memcpy(&slocal, s, sizeof(slocal)); 3221a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt s = &slocal; 3231a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 3241a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, "%s", _SL_); 3251a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", 3261a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt s->rx_compressed ? "compressed" : "", _SL_); 3271a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu", 3281a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_bytes, 3291a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_packets, 3301a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_errors, 3311a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_dropped, 3321a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_over_errors, 3331a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->multicast); 3341a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (s->rx_compressed) 3351a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " %-7llu", 3361a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_compressed); 3371a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (show_stats > 1) { 3381a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, "%s", _SL_); 3391a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); 3401a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " %-7llu %-7llu %-7llu %-7llu %-7llu", 3411a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_length_errors, 3421a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_crc_errors, 3431a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_frame_errors, 3441a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_fifo_errors, 3451a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->rx_missed_errors); 3461a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 3471a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, "%s", _SL_); 3481a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", 3491a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt s->tx_compressed ? "compressed" : "", _SL_); 3501a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu", 3511a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_bytes, 3521a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_packets, 3531a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_errors, 3541a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_dropped, 3551a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_carrier_errors, 3561a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->collisions); 3571a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (s->tx_compressed) 3581a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " %-7llu", 3591a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_compressed); 3601a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (show_stats > 1) { 3611a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, "%s", _SL_); 3621a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " TX errors: aborted fifo window heartbeat%s", _SL_); 3631a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, " %-7llu %-7llu %-7llu %-7llu", 3641a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_aborted_errors, 3651a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_fifo_errors, 3661a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_window_errors, 3671a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt (unsigned long long)s->tx_heartbeat_errors); 3681a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 3691a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 3701a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (do_link && !tb[IFLA_STATS64] && tb[IFLA_STATS] && show_stats) { 371dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtnl_link_stats slocal; 372dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtnl_link_stats *s = RTA_DATA(tb[IFLA_STATS]); 373dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (((unsigned long)s) & (sizeof(unsigned long)-1)) { 374dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(&slocal, s, sizeof(slocal)); 375dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s = &slocal; 376dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 377dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 378dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", 379dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_compressed ? "compressed" : "", _SL_); 380dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", 381dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_bytes, s->rx_packets, s->rx_errors, 382dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_dropped, s->rx_over_errors, 383dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->multicast 384dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ); 385dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (s->rx_compressed) 386dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-7u", s->rx_compressed); 387dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats > 1) { 388dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 389dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); 390dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-7u %-7u %-7u %-7u %-7u", 391dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_length_errors, 392dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_crc_errors, 393dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_frame_errors, 394dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_fifo_errors, 395dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->rx_missed_errors 396dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ); 397dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 398dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 399dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", 400dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_compressed ? "compressed" : "", _SL_); 401dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", 402dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_bytes, s->tx_packets, s->tx_errors, 403dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_dropped, s->tx_carrier_errors, s->collisions); 404dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (s->tx_compressed) 405dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-7u", s->tx_compressed); 406dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats > 1) { 407dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 408dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " TX errors: aborted fifo window heartbeat%s", _SL_); 409dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %-7u %-7u %-7u %-7u", 410dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_aborted_errors, 411dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_fifo_errors, 412dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_window_errors, 413dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat s->tx_heartbeat_errors 414dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ); 415dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 416dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 4171a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) { 4181a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST]; 4191a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt int rem = RTA_PAYLOAD(vflist); 4201a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) 4211a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt print_vfinfo(fp, i); 4221a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 4231a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 424dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "\n"); 425dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(fp); 426dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 427dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 428dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 429dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int flush_update(void) 430dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 431dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_send_check(&rth, filter.flushb, filter.flushp) < 0) { 432dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("Failed to send flush request"); 433dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 434dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 435dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushp = 0; 436dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 437dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 438dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 439dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int set_lifetime(unsigned int *lifetime, char *argv) 440dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 441dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(argv, "forever") == 0) 442dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *lifetime = INFINITY_LIFE_TIME; 443dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (get_u32(lifetime, argv, 0)) 444dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 445dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 446dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 447dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 448dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 449dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, 450dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *arg) 451dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 452dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat FILE *fp = (FILE*)arg; 453dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 454dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int len = n->nlmsg_len; 455dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int deprecated = 0; 456dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr * rta_tb[IFA_MAX+1]; 457dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char abuf[256]; 458dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 459dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 460dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) 461dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 462dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len -= NLMSG_LENGTH(sizeof(*ifa)); 463dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len < 0) { 464dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); 465dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 466dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 467dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 468dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.flushb && n->nlmsg_type != RTM_NEWADDR) 469dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 470dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 471dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); 472dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 473dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!rta_tb[IFA_LOCAL]) 474dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; 475dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!rta_tb[IFA_ADDRESS]) 476dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL]; 477dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 478dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.ifindex && filter.ifindex != ifa->ifa_index) 479dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 480dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((filter.scope^ifa->ifa_scope)&filter.scopemask) 481dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 482dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((filter.flags^ifa->ifa_flags)&filter.flagmask) 483dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 484dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.label) { 485dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 486dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const char *label; 487dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_LABEL]) 488dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat label = RTA_DATA(rta_tb[IFA_LABEL]); 489dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 490dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat label = ll_idx_n2a(ifa->ifa_index, b1); 491dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fnmatch(filter.label, label, 0) != 0) 492dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 493dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 494dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.pfx.family) { 495dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_LOCAL]) { 496dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix dst; 497dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&dst, 0, sizeof(dst)); 498dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst.family = ifa->ifa_family; 499dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL])); 500dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) 501dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 502dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 503dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 504dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 505dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family && filter.family != ifa->ifa_family) 506dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 507dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 508dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.flushb) { 509dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr *fn; 510dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { 511dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flush_update()) 512dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 513dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 514dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); 515dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(fn, n, n->nlmsg_len); 516dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fn->nlmsg_type = RTM_DELADDR; 517dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fn->nlmsg_flags = NLM_F_REQUEST; 518dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fn->nlmsg_seq = ++rth.seq; 519dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; 520dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushed++; 521dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats < 2) 522dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 523dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 524dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 525dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type == RTM_DELADDR) 526dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "Deleted "); 527dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 528dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.oneline || filter.flushb) 529dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); 530dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_family == AF_INET) 531dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " inet "); 532dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (ifa->ifa_family == AF_INET6) 533dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " inet6 "); 534dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (ifa->ifa_family == AF_DECnet) 535dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " dnet "); 536dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (ifa->ifa_family == AF_IPX) 537dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " ipx "); 538dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 539dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " family %d ", ifa->ifa_family); 540dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 541dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_LOCAL]) { 542dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", rt_addr_n2a(ifa->ifa_family, 543dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(rta_tb[IFA_LOCAL]), 544dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_DATA(rta_tb[IFA_LOCAL]), 545dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat abuf, sizeof(abuf))); 546dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 547dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_ADDRESS] == NULL || 548dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0) { 549dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "/%d ", ifa->ifa_prefixlen); 550dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 551dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " peer %s/%d ", 552dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rt_addr_n2a(ifa->ifa_family, 553dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(rta_tb[IFA_ADDRESS]), 554dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_DATA(rta_tb[IFA_ADDRESS]), 555dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat abuf, sizeof(abuf)), 556dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_prefixlen); 557dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 558dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 559dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 560dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_BROADCAST]) { 561dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "brd %s ", 562dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rt_addr_n2a(ifa->ifa_family, 563dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(rta_tb[IFA_BROADCAST]), 564dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_DATA(rta_tb[IFA_BROADCAST]), 565dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat abuf, sizeof(abuf))); 566dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 567dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_ANYCAST]) { 568dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "any %s ", 569dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat rt_addr_n2a(ifa->ifa_family, 570dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_PAYLOAD(rta_tb[IFA_ANYCAST]), 571dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat RTA_DATA(rta_tb[IFA_ANYCAST]), 572dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat abuf, sizeof(abuf))); 573dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 574dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1))); 575dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_SECONDARY) { 576dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_SECONDARY; 5771a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (ifa->ifa_family == AF_INET6) 5781a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, "temporary "); 5791a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt else 5801a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(fp, "secondary "); 581dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 582dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_TENTATIVE) { 583dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_TENTATIVE; 584dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "tentative "); 585dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 586dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_DEPRECATED) { 587dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_DEPRECATED; 588dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat deprecated = 1; 589dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "deprecated "); 590dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 591dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_HOMEADDRESS) { 592dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_HOMEADDRESS; 593dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "home "); 594dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 595dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_NODAD) { 596dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_NODAD; 597dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "nodad "); 598dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 599dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!(ifa->ifa_flags&IFA_F_PERMANENT)) { 600dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "dynamic "); 601dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else 602dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_PERMANENT; 603dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags&IFA_F_DADFAILED) { 604dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ifa->ifa_flags &= ~IFA_F_DADFAILED; 605dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "dadfailed "); 606dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 607dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags) 608dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "flags %02x ", ifa->ifa_flags); 609dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_LABEL]) 610dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", (char*)RTA_DATA(rta_tb[IFA_LABEL])); 611dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rta_tb[IFA_CACHEINFO]) { 612dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]); 613dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[128]; 614dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "%s", _SL_); 615dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ci->ifa_valid == INFINITY_LIFE_TIME) 616dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf, "valid_lft forever"); 617dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 618dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf, "valid_lft %usec", ci->ifa_valid); 619dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ci->ifa_prefered == INFINITY_LIFE_TIME) 620dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf+strlen(buf), " preferred_lft forever"); 621dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 622dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (deprecated) 623dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf+strlen(buf), " preferred_lft %dsec", 624dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ci->ifa_prefered); 625dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 626dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sprintf(buf+strlen(buf), " preferred_lft %usec", 627dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ci->ifa_prefered); 628dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 629dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, " %s", buf); 630dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 631dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(fp, "\n"); 632dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(fp); 633dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 634dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 635dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 636dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_addrinfo_primary(const struct sockaddr_nl *who, struct nlmsghdr *n, 637dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *arg) 638dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 639dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 640dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 641dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ifa->ifa_flags & IFA_F_SECONDARY) 642dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 643dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 644dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return print_addrinfo(who, n, arg); 645dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 646dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 647dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint print_addrinfo_secondary(const struct sockaddr_nl *who, struct nlmsghdr *n, 648dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *arg) 649dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 650dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 651dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 652dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_flags & IFA_F_SECONDARY) 653dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 654dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 655dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return print_addrinfo(who, n, arg); 656dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 657dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 658dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct nlmsg_list 659dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 660dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *next; 661dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr h; 662dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 663dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 664dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp) 665dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 666dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for ( ;ainfo ; ainfo = ainfo->next) { 667dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr *n = &ainfo->h; 668dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 669dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 670dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_type != RTM_NEWADDR) 671dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 672dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 673dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa))) 674dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 675dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 676dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_index != ifindex || 677dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (filter.family && filter.family != ifa->ifa_family)) 678dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 679dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 680dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_addrinfo(NULL, n, fp); 681dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 682dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 683dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 684dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 685dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 686dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, 687dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *arg) 688dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 689dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list **linfo = (struct nlmsg_list**)arg; 690dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *h; 691dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list **lp; 692dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 693dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat h = malloc(n->nlmsg_len+sizeof(void*)); 694dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (h == NULL) 695dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 696dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 697dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(&h->h, n, n->nlmsg_len); 698dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat h->next = NULL; 699dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 700dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */; 701dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *lp = h; 702dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 703dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ll_remember_index(who, n, NULL); 704dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 705dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 706dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 707dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int ipaddr_list_or_flush(int argc, char **argv, int flush) 708dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 709dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *linfo = NULL; 710dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *ainfo = NULL; 711dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *l, *n; 712dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *filter_dev = NULL; 713dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int no_link = 0; 714dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 715dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ipaddr_reset_filter(oneline); 716dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.showqueue = 1; 717dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 718dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family == AF_UNSPEC) 719dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.family = preferred_family; 720dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 721dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flush) { 722dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc <= 0) { 723dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Flush requires arguments.\n"); 724dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 725dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 726dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family == AF_PACKET) { 727dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Cannot flush link addresses.\n"); 728dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 729dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 730dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 731dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 732dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 733dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "to") == 0) { 734dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 735dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_prefix(&filter.pfx, *argv, filter.family); 736dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family == AF_UNSPEC) 737dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.family = filter.pfx.family; 738dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "scope") == 0) { 739dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned scope = 0; 740dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 741dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.scopemask = -1; 742dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_rtscope_a2n(&scope, *argv)) { 743dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "all") != 0) 744dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("invalid \"scope\"\n", *argv); 745dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat scope = RT_SCOPE_NOWHERE; 746dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.scopemask = 0; 747dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 748dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.scope = scope; 749dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "up") == 0) { 750dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.up = 1; 751dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "dynamic") == 0) { 752dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags &= ~IFA_F_PERMANENT; 753dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_PERMANENT; 754dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "permanent") == 0) { 755dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_PERMANENT; 756dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_PERMANENT; 7571a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } else if (strcmp(*argv, "secondary") == 0 || 7581a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt strcmp(*argv, "temporary") == 0) { 759dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_SECONDARY; 760dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_SECONDARY; 761dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "primary") == 0) { 762dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags &= ~IFA_F_SECONDARY; 763dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_SECONDARY; 764dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "tentative") == 0) { 765dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_TENTATIVE; 766dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_TENTATIVE; 767dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "deprecated") == 0) { 768dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_DEPRECATED; 769dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_DEPRECATED; 770dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "home") == 0) { 771dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_HOMEADDRESS; 772dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_HOMEADDRESS; 773dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "nodad") == 0) { 774dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flags |= IFA_F_NODAD; 775dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flagmask |= IFA_F_NODAD; 7761a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } else if (strcmp(*argv, "dadfailed") == 0) { 7771a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt filter.flags |= IFA_F_DADFAILED; 7781a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt filter.flagmask |= IFA_F_DADFAILED; 779dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "label") == 0) { 780dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 781dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.label = *argv; 782dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 783dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "dev") == 0) { 784dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 785dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 786dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "help") == 0) 787dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 788dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter_dev) 789dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg2("dev", *argv); 790dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter_dev = *argv; 791dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 792dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argv++; argc--; 793dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 794dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 795dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) { 796dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("Cannot send dump request"); 797dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 798dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 799dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 800dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) { 801dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Dump terminated\n"); 802dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 803dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 804dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 805dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter_dev) { 806dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.ifindex = ll_name_to_index(filter_dev); 807dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.ifindex <= 0) { 808dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Device \"%s\" does not exist.\n", filter_dev); 809dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 810dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 811dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 812dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 813dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flush) { 814dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int round = 0; 815dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char flushb[4096-512]; 816dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 817dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushb = flushb; 818dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushp = 0; 819dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushe = sizeof(flushb); 820dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 821dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (round < MAX_ROUNDS) { 822dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const struct rtnl_dump_filter_arg a[3] = { 823dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 824dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .filter = print_addrinfo_secondary, 825dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg1 = stdout, 826dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .junk = NULL, 827dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg2 = NULL 828dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat }, 829dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 830dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .filter = print_addrinfo_primary, 831dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg1 = stdout, 832dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .junk = NULL, 833dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg2 = NULL 834dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat }, 835dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat { 836dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .filter = NULL, 837dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg1 = NULL, 838dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .junk = NULL, 839dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .arg2 = NULL 840dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat }, 841dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat }; 842dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 843dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("Cannot send dump request"); 844dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 845dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 846dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.flushed = 0; 847dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_dump_filter_l(&rth, a) < 0) { 848dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Flush terminated\n"); 849dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 850dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 851dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.flushed == 0) { 852dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats) { 853dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (round == 0) 854dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("Nothing to flush.\n"); 855dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 856dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":""); 857dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 858dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(stdout); 859dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 860dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 861dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat round++; 862dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (flush_update() < 0) 863dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 1; 864dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 865dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats) { 866dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed); 867dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(stdout); 868dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 869dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 870dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "*** Flush remains incomplete after %d rounds. ***\n", MAX_ROUNDS); fflush(stderr); 871dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 1; 872dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 873dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 874dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family != AF_PACKET) { 875dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 876dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat perror("Cannot send dump request"); 877dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 878dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 879dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 880dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) { 881dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Dump terminated\n"); 882dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(1); 883dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 884dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 885dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 886dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 887dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family && filter.family != AF_PACKET) { 888dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list **lp; 889dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lp=&linfo; 890dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 891dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.oneline) 892dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat no_link = 1; 893dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 894dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while ((l=*lp)!=NULL) { 895dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int ok = 0; 896dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 897dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsg_list *a; 898dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 899dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (a=ainfo; a; a=a->next) { 900dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr *n = &a->h; 901dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg *ifa = NLMSG_DATA(n); 902dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 903dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (ifa->ifa_index != ifi->ifi_index || 904dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (filter.family && filter.family != ifa->ifa_family)) 905dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 906dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((filter.scope^ifa->ifa_scope)&filter.scopemask) 907dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 908dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((filter.flags^ifa->ifa_flags)&filter.flagmask) 909dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 910dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.pfx.family || filter.label) { 911dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tb[IFA_MAX+1]; 912dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n)); 913dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!tb[IFA_LOCAL]) 914dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tb[IFA_LOCAL] = tb[IFA_ADDRESS]; 915dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 916dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.pfx.family && tb[IFA_LOCAL]) { 917dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix dst; 918dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&dst, 0, sizeof(dst)); 919dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dst.family = ifa->ifa_family; 920dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL])); 921dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) 922dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 923dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 924dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.label) { 925dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 926dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const char *label; 927dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFA_LABEL]) 928dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat label = RTA_DATA(tb[IFA_LABEL]); 929dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 930dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat label = ll_idx_n2a(ifa->ifa_index, b1); 931dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (fnmatch(filter.label, label, 0) != 0) 932dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 933dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 934dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 935dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 936dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ok = 1; 937dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 938dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 939dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ok) 940dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *lp = l->next; 941dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 942dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lp = &l->next; 943dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 944dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 945dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 946dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (l=linfo; l; l = n) { 947dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat n = l->next; 948dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) { 949dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 950dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (filter.family != AF_PACKET) 951dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_selected_addrinfo(ifi->ifi_index, ainfo, stdout); 952dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 953dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fflush(stdout); 954dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat free(l); 955dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 956dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 957dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 958dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 959dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 960dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint ipaddr_list_link(int argc, char **argv) 961dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 962dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat preferred_family = AF_PACKET; 963dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat do_link = 1; 964dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_list_or_flush(argc, argv, 0); 965dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 966dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 967dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatvoid ipaddr_reset_filter(int oneline) 968dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 969dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&filter, 0, sizeof(filter)); 970dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat filter.oneline = oneline; 971dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 972dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 973dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int default_scope(inet_prefix *lcl) 974dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 975dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lcl->family == AF_INET) { 976dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127) 977dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return RT_SCOPE_HOST; 978dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 979dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 980dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 981dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 982dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int ipaddr_modify(int cmd, int flags, int argc, char **argv) 983dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 984dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct { 985dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr n; 986dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifaddrmsg ifa; 987dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[256]; 988dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } req; 989dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *d = NULL; 990dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *l = NULL; 991dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *lcl_arg = NULL; 992dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *valid_lftp = NULL; 993dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *preferred_lftp = NULL; 994dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix lcl; 995dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix peer; 996dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int local_len = 0; 997dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int peer_len = 0; 998dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int brd_len = 0; 999dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int any_len = 0; 1000dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int scoped = 0; 1001dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 preferred_lft = INFINITY_LIFE_TIME; 1002dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 valid_lft = INFINITY_LIFE_TIME; 1003dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifa_cacheinfo cinfo; 1004dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1005dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&req, 0, sizeof(req)); 1006dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1007dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); 1008dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.n.nlmsg_flags = NLM_F_REQUEST | flags; 1009dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.n.nlmsg_type = cmd; 1010dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = preferred_family; 1011dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1012dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 1013dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "peer") == 0 || 1014dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "remote") == 0) { 1015dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 1016dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1017dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (peer_len) 1018dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("peer", *argv); 1019dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_prefix(&peer, *argv, req.ifa.ifa_family); 1020dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat peer_len = peer.bytelen; 1021dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family == AF_UNSPEC) 1022dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = peer.family; 1023dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen); 1024dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_prefixlen = peer.bitlen; 1025dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "broadcast") == 0 || 1026dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "brd") == 0) { 1027dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix addr; 1028dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 1029dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (brd_len) 1030dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("broadcast", *argv); 1031dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "+") == 0) 1032dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd_len = -1; 1033dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else if (strcmp(*argv, "-") == 0) 1034dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd_len = -2; 1035dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 1036dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_addr(&addr, *argv, req.ifa.ifa_family); 1037dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family == AF_UNSPEC) 1038dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = addr.family; 1039dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen); 1040dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd_len = addr.bytelen; 1041dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1042dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "anycast") == 0) { 1043dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix addr; 1044dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 1045dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (any_len) 1046dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("anycast", *argv); 1047dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_addr(&addr, *argv, req.ifa.ifa_family); 1048dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family == AF_UNSPEC) 1049dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = addr.family; 1050dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); 1051dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat any_len = addr.bytelen; 1052dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "scope") == 0) { 1053dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned scope = 0; 1054dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 1055dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_rtscope_a2n(&scope, *argv)) 1056dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg(*argv, "invalid scope value."); 1057dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_scope = scope; 1058dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat scoped = 1; 1059dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "dev") == 0) { 1060dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 1061dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat d = *argv; 1062dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "label") == 0) { 1063dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 1064dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat l = *argv; 1065dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1); 1066dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "valid_lft") == 0) { 1067dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (valid_lftp) 1068dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("valid_lft", *argv); 1069dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 1070dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat valid_lftp = *argv; 1071dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (set_lifetime(&valid_lft, *argv)) 1072dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("valid_lft value", *argv); 1073dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "preferred_lft") == 0) { 1074dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (preferred_lftp) 1075dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg("preferred_lft", *argv); 1076dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 1077dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat preferred_lftp = *argv; 1078dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (set_lifetime(&preferred_lft, *argv)) 1079dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("preferred_lft value", *argv); 1080dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "home") == 0) { 1081dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_flags |= IFA_F_HOMEADDRESS; 1082dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "nodad") == 0) { 1083dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_flags |= IFA_F_NODAD; 1084dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 1085dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "local") == 0) { 1086dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 1087dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1088dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "help") == 0) 1089dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 1090dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (local_len) 1091dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat duparg2("local", *argv); 1092dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat lcl_arg = *argv; 1093dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat get_prefix(&lcl, *argv, req.ifa.ifa_family); 1094dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family == AF_UNSPEC) 1095dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_family = lcl.family; 1096dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); 1097dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat local_len = lcl.bytelen; 1098dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1099dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 1100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (d == NULL) { 1102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Not enough information: \"dev\" argument is required.\n"); 1103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (l && matches(d, l) != 0) { 1106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l); 11071a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return -1; 1108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (peer_len == 0 && local_len) { 1111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) { 1112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, 1113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \ 1114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \ 1115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat " This special behaviour is likely to disappear in further releases,\n" \ 1116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat " fix your scripts!\n", lcl_arg, local_len*8); 1117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 1118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat peer = lcl; 1119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen); 1120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_prefixlen == 0) 1123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_prefixlen = lcl.bitlen; 1124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (brd_len < 0 && cmd != RTM_DELADDR) { 1126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix brd; 1127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 1128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (req.ifa.ifa_family != AF_INET) { 1129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Broadcast can be set only for IPv4 addresses\n"); 1130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd = peer; 1133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (brd.bitlen <= 30) { 1134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i=31; i>=brd.bitlen; i--) { 1135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (brd_len == -1) 1136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd.data[0] |= htonl(1<<(31-i)); 1137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 1138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd.data[0] &= ~htonl(1<<(31-i)); 1139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen); 1141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat brd_len = brd.bytelen; 1142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!scoped && cmd != RTM_DELADDR) 1145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.ifa.ifa_scope = default_scope(&lcl); 1146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ll_init_map(&rth); 1148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) { 1150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Cannot find device \"%s\"\n", d); 1151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (valid_lftp || preferred_lftp) { 1155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!valid_lft) { 1156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "valid_lft is zero\n"); 1157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (valid_lft < preferred_lft) { 1160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "preferred_lft is greater than valid_lft\n"); 1161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 1162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&cinfo, 0, sizeof(cinfo)); 1165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cinfo.ifa_prefered = preferred_lft; 1166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat cinfo.ifa_valid = valid_lft; 1167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo, 1168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sizeof(cinfo)); 1169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 1170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 11721a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return -2; 1173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 1175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 1176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint do_ipaddr(int argc, char **argv) 1178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 1179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc < 1) 1180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_list_or_flush(0, NULL, 0); 1181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "add") == 0) 1182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1); 1183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "change") == 0 || 1184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "chg") == 0) 1185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_modify(RTM_NEWADDR, NLM_F_REPLACE, argc-1, argv+1); 1186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "replace") == 0) 1187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1); 1188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "delete") == 0) 1189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_modify(RTM_DELADDR, 0, argc-1, argv+1); 1190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 1191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat || matches(*argv, "lst") == 0) 1192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_list_or_flush(argc-1, argv+1, 0); 1193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "flush") == 0) 1194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return ipaddr_list_or_flush(argc-1, argv+1, 1); 1195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "help") == 0) 1196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 1197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv); 1198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 1199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 1200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 1201