dect
/
libnl
Archived
13
0
Fork 0

Improvements to address utilities

- Moved env var dumping to nl-addr-list.c
- support for ipv6 lifetimes
- correct and complete help texts
This commit is contained in:
Thomas Graf 2008-06-17 02:52:18 +02:00
parent 1f66555570
commit ab578b9ca0
7 changed files with 294 additions and 188 deletions

View File

@ -74,6 +74,13 @@ extern struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *);
extern int rtnl_addr_set_multicast(struct rtnl_addr *, struct nl_addr *);
extern struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *);
extern uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *);
extern void rtnl_addr_set_valid_lifetime(struct rtnl_addr *, uint32_t);
extern uint32_t rtnl_addr_get_preferred_lifetime(struct rtnl_addr *);
extern void rtnl_addr_set_preferred_lifetime(struct rtnl_addr *, uint32_t);
extern uint32_t rtnl_addr_get_create_time(struct rtnl_addr *);
extern uint32_t rtnl_addr_get_last_update_time(struct rtnl_addr *);
#ifdef __cplusplus
}
#endif

View File

@ -131,6 +131,13 @@ static struct nl_cache_ops rtnl_addr_ops;
static struct nl_object_ops addr_obj_ops;
/** @endcond */
static void addr_constructor(struct nl_object *obj)
{
struct rtnl_addr *addr = nl_object_priv(obj);
addr->a_scope = RT_SCOPE_NOWHERE;
}
static void addr_free_data(struct nl_object *obj)
{
struct rtnl_addr *addr = nl_object_priv(obj);
@ -383,28 +390,16 @@ static void addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
nl_dump_line(p, " <family>%s</family>\n",
nl_af2str(addr->a_family, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_LOCAL)
nl_dump_line(p, " <local>%s</local>\n",
nl_addr2str(addr->a_local, buf, sizeof(buf)));
nl_dump_line(p, " <local>%s</local>\n",
nl_addr2str(addr->a_local, buf, sizeof(buf)));
nl_dump_line(p, " <peer>%s</peer>\n",
nl_addr2str(addr->a_peer, buf, sizeof(buf)));
nl_dump_line(p, " <broadcast>%s</broadcast>\n",
nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
nl_dump_line(p, " <multicast>%s</multicast>\n",
nl_addr2str(addr->a_multicast, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_PEER)
nl_dump_line(p, " <peer>%s</peer>\n",
nl_addr2str(addr->a_peer, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_BROADCAST)
nl_dump_line(p, " <broadcast>%s</broadcast>\n",
nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_MULTICAST)
nl_dump_line(p, " <multicast>%s</multicast>\n",
nl_addr2str(addr->a_multicast, buf,
sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
nl_dump_line(p, " <prefixlen>%u</prefixlen>\n",
addr->a_prefixlen);
link_cache = nl_cache_mngt_require("route/link");
if (link_cache)
nl_dump_line(p, " <device>%s</device>\n",
rtnl_link_i2name(link_cache, addr->a_ifindex,
@ -412,12 +407,10 @@ static void addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
else
nl_dump_line(p, " <device>%u</device>\n", addr->a_ifindex);
if (addr->ce_mask & ADDR_ATTR_SCOPE)
nl_dump_line(p, " <scope>%s</scope>\n",
rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
nl_dump_line(p, " <scope>%s</scope>\n",
rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_LABEL)
nl_dump_line(p, " <label>%s</label>\n", addr->a_label);
nl_dump_line(p, " <label>%s</label>\n", addr->a_label);
rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
if (buf[0])
@ -427,23 +420,23 @@ static void addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
nl_dump_line(p, " <cacheinfo>\n");
nl_dump_line(p, " <valid>%s</valid>\n",
ci->aci_valid == 0xFFFFFFFFU ? "forever" :
nl_msec2str(ci->aci_valid * 1000,
buf, sizeof(buf)));
if (ci->aci_valid == 0xFFFFFFFFU)
nl_dump_line(p, " <valid>forever</valid>\n");
else
nl_dump_line(p, " <valid>%u</valid>\n",
ci->aci_valid);
nl_dump_line(p, " <prefered>%s</prefered>\n",
ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
nl_msec2str(ci->aci_prefered * 1000,
buf, sizeof(buf)));
if (ci->aci_prefered == 0xFFFFFFFFU)
nl_dump_line(p, " <preferred>forever</preferred>\n");
else
nl_dump_line(p, " <preferred>%s</preferred>\n",
ci->aci_prefered);
nl_dump_line(p, " <created>%s</created>\n",
nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
buf, sizeof(buf)));
nl_dump_line(p, " <created>%u</created>\n",
addr->a_cacheinfo.aci_cstamp);
nl_dump_line(p, " <last-update>%s</last-update>\n",
nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
buf, sizeof(buf)));
nl_dump_line(p, " <last-update>%u</last-update>\n",
addr->a_cacheinfo.aci_tstamp);
nl_dump_line(p, " </cacheinfo>\n");
}
@ -451,77 +444,6 @@ static void addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
nl_dump_line(p, "</address>\n");
}
static void addr_dump_env(struct nl_object *obj, struct nl_dump_params *p)
{
struct rtnl_addr *addr = (struct rtnl_addr *) obj;
struct nl_cache *link_cache;
char buf[128];
nl_dump_line(p, "ADDR_FAMILY=%s\n",
nl_af2str(addr->a_family, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_LOCAL)
nl_dump_line(p, "ADDR_LOCAL=%s\n",
nl_addr2str(addr->a_local, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_PEER)
nl_dump_line(p, "ADDR_PEER=%s\n",
nl_addr2str(addr->a_peer, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_BROADCAST)
nl_dump_line(p, "ADDR_BROADCAST=%s\n",
nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_MULTICAST)
nl_dump_line(p, "ADDR_MULTICAST=%s\n",
nl_addr2str(addr->a_multicast, buf,
sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
nl_dump_line(p, "ADDR_PREFIXLEN=%u\n",
addr->a_prefixlen);
link_cache = nl_cache_mngt_require("route/link");
nl_dump_line(p, "ADDR_IFINDEX=%u\n", addr->a_ifindex);
if (link_cache)
nl_dump_line(p, "ADDR_IFNAME=%s\n",
rtnl_link_i2name(link_cache, addr->a_ifindex,
buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_SCOPE)
nl_dump_line(p, "ADDR_SCOPE=%s\n",
rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
if (addr->ce_mask & ADDR_ATTR_LABEL)
nl_dump_line(p, "ADDR_LABEL=%s\n", addr->a_label);
rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
if (buf[0])
nl_dump_line(p, "ADDR_FLAGS=%s\n", buf);
if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
nl_dump_line(p, "ADDR_CACHEINFO_VALID=%s\n",
ci->aci_valid == 0xFFFFFFFFU ? "forever" :
nl_msec2str(ci->aci_valid * 1000,
buf, sizeof(buf)));
nl_dump_line(p, "ADDR_CACHEINFO_PREFERED=%s\n",
ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
nl_msec2str(ci->aci_prefered * 1000,
buf, sizeof(buf)));
nl_dump_line(p, "ADDR_CACHEINFO_CREATED=%s\n",
nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
buf, sizeof(buf)));
nl_dump_line(p, "ADDR_CACHEINFO_LASTUPDATE=%s\n",
nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
buf, sizeof(buf)));
}
}
static int addr_compare(struct nl_object *_a, struct nl_object *_b,
uint32_t attrs, int flags)
{
@ -644,6 +566,16 @@ static int build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags,
if (tmpl->ce_mask & ADDR_ATTR_BROADCAST)
NLA_PUT_ADDR(msg, IFA_BROADCAST, tmpl->a_bcast);
if (tmpl->ce_mask & ADDR_ATTR_CACHEINFO) {
struct ifa_cacheinfo ca = {
.ifa_valid = tmpl->a_cacheinfo.aci_valid,
.ifa_prefered = tmpl->a_cacheinfo.aci_prefered,
};
NLA_PUT(msg, IFA_CACHEINFO, sizeof(ca), &ca);
}
*result = msg;
return 0;
@ -849,10 +781,7 @@ void rtnl_addr_set_prefixlen(struct rtnl_addr *addr, int prefix)
int rtnl_addr_get_prefixlen(struct rtnl_addr *addr)
{
if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
return addr->a_prefixlen;
else
return -1;
return addr->a_prefixlen;
}
void rtnl_addr_set_scope(struct rtnl_addr *addr, int scope)
@ -863,10 +792,7 @@ void rtnl_addr_set_scope(struct rtnl_addr *addr, int scope)
int rtnl_addr_get_scope(struct rtnl_addr *addr)
{
if (addr->ce_mask & ADDR_ATTR_SCOPE)
return addr->a_scope;
else
return -1;
return addr->a_scope;
}
void rtnl_addr_set_flags(struct rtnl_addr *addr, unsigned int flags)
@ -924,10 +850,7 @@ int rtnl_addr_set_local(struct rtnl_addr *addr, struct nl_addr *local)
struct nl_addr *rtnl_addr_get_local(struct rtnl_addr *addr)
{
if (addr->ce_mask & ADDR_ATTR_LOCAL)
return addr->a_local;
else
return NULL;
return addr->a_local;
}
int rtnl_addr_set_peer(struct rtnl_addr *addr, struct nl_addr *peer)
@ -942,10 +865,7 @@ int rtnl_addr_set_peer(struct rtnl_addr *addr, struct nl_addr *peer)
struct nl_addr *rtnl_addr_get_peer(struct rtnl_addr *addr)
{
if (addr->ce_mask & ADDR_ATTR_PEER)
return addr->a_peer;
else
return NULL;
return addr->a_peer;
}
int rtnl_addr_set_broadcast(struct rtnl_addr *addr, struct nl_addr *bcast)
@ -955,10 +875,7 @@ int rtnl_addr_set_broadcast(struct rtnl_addr *addr, struct nl_addr *bcast)
struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *addr)
{
if (addr->ce_mask & ADDR_ATTR_BROADCAST)
return addr->a_bcast;
else
return NULL;
return addr->a_bcast;
}
int rtnl_addr_set_multicast(struct rtnl_addr *addr, struct nl_addr *multicast)
@ -969,10 +886,45 @@ int rtnl_addr_set_multicast(struct rtnl_addr *addr, struct nl_addr *multicast)
struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *addr)
{
if (addr->ce_mask & ADDR_ATTR_MULTICAST)
return addr->a_multicast;
return addr->a_multicast;
}
uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *addr)
{
if (addr->ce_mask & ADDR_ATTR_CACHEINFO)
return addr->a_cacheinfo.aci_valid;
else
return NULL;
return 0xFFFFFFFFU;
}
void rtnl_addr_set_valid_lifetime(struct rtnl_addr *addr, uint32_t lifetime)
{
addr->a_cacheinfo.aci_valid = lifetime;
addr->ce_mask |= ADDR_ATTR_CACHEINFO;
}
uint32_t rtnl_addr_get_preferred_lifetime(struct rtnl_addr *addr)
{
if (addr->ce_mask & ADDR_ATTR_CACHEINFO)
return addr->a_cacheinfo.aci_prefered;
else
return 0xFFFFFFFFU;
}
void rtnl_addr_set_preferred_lifetime(struct rtnl_addr *addr, uint32_t lifetime)
{
addr->a_cacheinfo.aci_prefered = lifetime;
addr->ce_mask |= ADDR_ATTR_CACHEINFO;
}
uint32_t rtnl_addr_get_create_time(struct rtnl_addr *addr)
{
return addr->a_cacheinfo.aci_cstamp;
}
uint32_t rtnl_addr_get_last_update_time(struct rtnl_addr *addr)
{
return addr->a_cacheinfo.aci_tstamp;
}
/** @} */
@ -984,6 +936,9 @@ struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *addr)
static struct trans_tbl addr_flags[] = {
__ADD(IFA_F_SECONDARY, secondary)
__ADD(IFA_F_NODAD, nodad)
__ADD(IFA_F_OPTIMISTIC, optimistic)
__ADD(IFA_F_HOMEADDRESS, homeaddress)
__ADD(IFA_F_DEPRECATED, deprecated)
__ADD(IFA_F_TENTATIVE, tentative)
__ADD(IFA_F_PERMANENT, permanent)
@ -1005,6 +960,7 @@ int rtnl_addr_str2flags(const char *name)
static struct nl_object_ops addr_obj_ops = {
.oo_name = "route/addr",
.oo_size = sizeof(struct rtnl_addr),
.oo_constructor = addr_constructor,
.oo_free_data = addr_free_data,
.oo_clone = addr_clone,
.oo_dump = {
@ -1012,7 +968,6 @@ static struct nl_object_ops addr_obj_ops = {
[NL_DUMP_DETAILS] = addr_dump_details,
[NL_DUMP_STATS] = addr_dump_stats,
[NL_DUMP_XML] = addr_dump_xml,
[NL_DUMP_ENV] = addr_dump_env,
},
.oo_compare = addr_compare,
.oo_attrs2str = addr_attrs2str,

View File

@ -96,3 +96,27 @@ void parse_broadcast(struct rtnl_addr *addr, char *arg)
nl_addr_put(a);
}
static uint32_t parse_lifetime(const char *arg)
{
uint64_t msecs;
int err;
if (!strcasecmp(arg, "forever"))
return 0xFFFFFFFFU;
if ((err = nl_str2msec(arg, &msecs)) < 0)
fatal(err, "Unable to parse time string \"%s\": %s",
arg, nl_geterror(err));
return (msecs / 1000);
}
void parse_preferred(struct rtnl_addr *addr, char *arg)
{
rtnl_addr_set_preferred_lifetime(addr, parse_lifetime(arg));
}
void parse_valid(struct rtnl_addr *addr, char *arg)
{
rtnl_addr_set_valid_lifetime(addr, parse_lifetime(arg));
}

View File

@ -22,5 +22,7 @@ extern void parse_label(struct rtnl_addr *, char *);
extern void parse_peer(struct rtnl_addr *, char *);
extern void parse_scope(struct rtnl_addr *, char *);
extern void parse_broadcast(struct rtnl_addr *, char *);
extern void parse_preferred(struct rtnl_addr *, char *);
extern void parse_valid(struct rtnl_addr *, char *);
#endif

View File

@ -15,21 +15,24 @@ static int quiet = 0;
static void print_usage(void)
{
printf(
"Usage: nl-addr-add [OPTION]... [ADDRESS]\n"
"\n"
"Options\n"
" -q, --quiet Do not print informal notifications\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Address Options\n"
" -a, --local=ADDR local address, e.g. 10.0.0.1\n"
" -d, --dev=DEV device the address is on\n"
" --family=FAMILY address family\n"
" --label=STRING address label\n"
" --peer=ADDR peer address\n"
" --scope=SCOPE address scope\n"
" --broadcast=ADDR broadcast address\n"
"Usage: nl-addr-add [OPTION]... [ADDRESS]\n"
"\n"
"Options\n"
" --replace Replace the address if it exists.\n"
" -q, --quiet Do not print informal notifications.\n"
" -h, --help Show this help.\n"
" -v, --version Show versioning information.\n"
"\n"
"Address Options\n"
" -a, --local=ADDR Address to be considered local.\n"
" -d, --dev=DEV Device the address should be assigned to.\n"
" --family=FAMILY Address family (normally autodetected).\n"
" --broadcast=ADDR Broadcast address of network (IPv4).\n"
" --peer=ADDR Peer address (IPv4).\n"
" --label=STRING Additional address label (IPv4).\n"
" --scope=SCOPE Scope of local address (IPv4).\n"
" --preferred=TIME Preferred lifetime (IPv6).\n"
" --valid=TIME Valid lifetime (IPv6).\n"
);
exit(0);
@ -44,7 +47,7 @@ int main(int argc, char *argv[])
.dp_type = NL_DUMP_LINE,
.dp_fd = stdout,
};
int err;
int err, nlflags = NLM_F_CREATE;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
@ -59,8 +62,12 @@ int main(int argc, char *argv[])
ARG_PEER,
ARG_SCOPE,
ARG_BROADCAST,
ARG_REPLACE,
ARG_PREFERRED,
ARG_VALID,
};
static struct option long_opts[] = {
{ "replace", 0, 0, ARG_REPLACE },
{ "quiet", 0, 0, 'q' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
@ -71,6 +78,8 @@ int main(int argc, char *argv[])
{ "peer", 1, 0, ARG_PEER },
{ "scope", 1, 0, ARG_SCOPE },
{ "broadcast", 1, 0, ARG_BROADCAST },
{ "preferred", 1, 0, ARG_PREFERRED },
{ "valid", 1, 0, ARG_VALID },
{ 0, 0, 0, 0 }
};
@ -79,6 +88,8 @@ int main(int argc, char *argv[])
break;
switch (c) {
case '?': exit(NLE_INVAL);
case ARG_REPLACE: nlflags |= NLM_F_REPLACE; break;
case 'q': quiet = 1; break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
@ -89,11 +100,13 @@ int main(int argc, char *argv[])
case ARG_PEER: parse_peer(addr, optarg); break;
case ARG_SCOPE: parse_scope(addr, optarg); break;
case ARG_BROADCAST: parse_broadcast(addr, optarg); break;
case ARG_PREFERRED: parse_preferred(addr, optarg); break;
case ARG_VALID: parse_valid(addr, optarg); break;
}
}
if ((err = rtnl_addr_add(sock, addr, 0)) < 0)
fatal(err, "Unable to add address: %s\n", nl_geterror(err));
if ((err = rtnl_addr_add(sock, addr, nlflags)) < 0)
fatal(err, "Unable to add address: %s", nl_geterror(err));
if (!quiet) {
printf("Added ");

View File

@ -17,23 +17,26 @@ static int deleted = 0;
static void print_usage(void)
{
printf(
"Usage: nl-addr-delete [OPTION]... [ADDRESS]\n"
"\n"
"Options\n"
" -i, --interactive Run interactively\n"
" --yes Set default answer to yes\n"
" -q, --quiet Do not print informal notifications\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Address Options\n"
" -a, --local=ADDR local address, e.g. 10.0.0.1\n"
" -d, --dev=DEV device the address is on\n"
" --family=FAMILY address family\n"
" --label=STRING address label\n"
" --peer=ADDR peer address\n"
" --scope=SCOPE address scope\n"
" --broadcast=ADDR broadcast address\n"
"Usage: nl-addr-delete [OPTION]... [ADDRESS]\n"
"\n"
"Options\n"
" -i, --interactive Run interactively.\n"
" --yes Set default answer to yes.\n"
" -q, --quiet Do not print informal notifications.\n"
" -h, --help Show this help.\n"
" -v, --version Show versioning information.\n"
"\n"
"Address Options\n"
" -a, --local=ADDR Local address.\n"
" -d, --dev=DEV Associated network device.\n"
" --family=FAMILY Family of local address.\n"
" --label=STRING Address label (IPv4).\n"
" --peer=ADDR Peer address (IPv4).\n"
" --scope=SCOPE Address scope (IPv4).\n"
" --broadcast=ADDR Broadcast address of network (IPv4).\n"
" --valid-lifetime=TS Valid lifetime before route expires (IPv6).\n"
" --preferred=TIME Preferred lifetime (IPv6).\n"
" --valid=TIME Valid lifetime (IPv6).\n"
);
exit(0);
@ -82,6 +85,8 @@ int main(int argc, char *argv[])
ARG_PEER,
ARG_SCOPE,
ARG_BROADCAST,
ARG_PREFERRED,
ARG_VALID,
};
static struct option long_opts[] = {
{ "interactive", 0, 0, 'i' },
@ -96,6 +101,8 @@ int main(int argc, char *argv[])
{ "peer", 1, 0, ARG_PEER },
{ "scope", 1, 0, ARG_SCOPE },
{ "broadcast", 1, 0, ARG_BROADCAST },
{ "preferred", 1, 0, ARG_PREFERRED },
{ "valid", 1, 0, ARG_VALID },
{ 0, 0, 0, 0 }
};
@ -116,6 +123,8 @@ int main(int argc, char *argv[])
case ARG_PEER: parse_peer(addr, optarg); break;
case ARG_SCOPE: parse_scope(addr, optarg); break;
case ARG_BROADCAST: parse_broadcast(addr, optarg); break;
case ARG_PREFERRED: parse_preferred(addr, optarg); break;
case ARG_VALID: parse_valid(addr, optarg); break;
}
}

View File

@ -13,25 +13,99 @@
static void print_usage(void)
{
printf(
"Usage: nl-addr-list [OPTION]... [ADDRESS]\n"
"\n"
"Options\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Address Options\n"
" -a, --local=ADDR local address, e.g. 10.0.0.1\n"
" -d, --dev=DEV device the address is on\n"
" --family=FAMILY address family\n"
" --label=STRING address label\n"
" --peer=ADDR peer address\n"
" --scope=SCOPE address scope\n"
" --broadcast=ADDR broadcast address\n"
"Usage: nl-addr-list [OPTION]... [ADDRESS]\n"
"\n"
"Options\n"
" --details Show details on multiple lines.\n"
" --env Print address details in sh env variable syntax.\n"
" --prefix=STRING Prefix each printed line.\n"
" -h, --help Show this help.\n"
" -v, --version Show versioning information.\n"
"\n"
"Address Selection\n"
" -a, --local=ADDR Local address.\n"
" -d, --dev=DEV Associated network device.\n"
" --family=FAMILY Family of local address.\n"
" --label=STRING Address label (IPv4).\n"
" --peer=ADDR Peer address (IPv4).\n"
" --scope=SCOPE Address scope (IPv4).\n"
" --broadcast=ADDR Broadcast address of network (IPv4).\n"
" --valid-lifetime=TS Valid lifetime before route expires (IPv6).\n"
" --preferred=TIME Preferred lifetime (IPv6).\n"
" --valid=TIME Valid lifetime (IPv6).\n"
);
exit(0);
}
static char *prefix;
void print_prefix(struct nl_dump_params *p, int line)
{
if (prefix)
nl_dump(p, "%s", prefix);
}
static void env_dump(struct nl_object *obj, void *arg)
{
struct nl_dump_params *p = arg;
struct rtnl_addr *addr = (struct rtnl_addr *) obj;
struct nl_cache *link_cache;
struct nl_addr *a;
static int index = 0;
char buf[128], pfx[32], *s;
snprintf(pfx, sizeof(pfx), "ADDR%d", index++);
nl_dump_line(p, "%s_FAMILY=%s\n", pfx,
nl_af2str(rtnl_addr_get_family(addr), buf, sizeof(buf)));
nl_dump_line(p, "%s_LOCAL=%s\n", pfx,
nl_addr2str(rtnl_addr_get_local(addr), buf, sizeof(buf)));
nl_dump_line(p, "%s_IFINDEX=%u\n", pfx, rtnl_addr_get_ifindex(addr));
link_cache = nl_cache_mngt_require("route/link");
if (link_cache)
nl_dump_line(p, "%s_IFNAME=%s\n", pfx,
rtnl_link_i2name(link_cache,
rtnl_addr_get_ifindex(addr),
buf, sizeof(buf)));
if ((a = rtnl_addr_get_peer(addr)))
nl_dump_line(p, "%s_PEER=%s\n", pfx,
nl_addr2str(a, buf, sizeof(buf)));
if ((a = rtnl_addr_get_broadcast(addr)))
nl_dump_line(p, "%s_BROADCAST=%s\n", pfx,
nl_addr2str(a, buf, sizeof(buf)));
nl_dump_line(p, "%s_SCOPE=%s\n", pfx,
rtnl_scope2str(rtnl_addr_get_scope(addr),
buf, sizeof(buf)));
if ((s = rtnl_addr_get_label(addr)))
nl_dump_line(p, "%s_LABEL=%s\n", pfx, s);
rtnl_addr_flags2str(rtnl_addr_get_flags(addr), buf, sizeof(buf));
if (buf[0])
nl_dump_line(p, "%s_FLAGS=%s\n", pfx, buf);
nl_dump_line(p, "%s_CACHEINFO_VALID=%u\n", pfx,
rtnl_addr_get_valid_lifetime(addr));
#if 0
if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
nl_dump_line(p, "ADDR_CACHEINFO_PREFERRED=%u\n",
ci->aci_prefered);
nl_dump_line(p, "ADDR_CACHEINFO_CREATED=%u\n", ci->aci_cstamp);
nl_dump_line(p, "ADDR_CACHEINFO_LASTUPDATE=%u\n",
ci->aci_tstamp);
}
#endif
}
int main(int argc, char *argv[])
{
struct nl_handle *sock;
@ -39,8 +113,10 @@ int main(int argc, char *argv[])
struct nl_cache *link_cache, *addr_cache;
struct nl_dump_params params = {
.dp_type = NL_DUMP_LINE,
.dp_nl_cb = print_prefix,
.dp_fd = stdout,
};
int dump_env = 0;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
@ -56,9 +132,16 @@ int main(int argc, char *argv[])
ARG_PEER,
ARG_SCOPE,
ARG_BROADCAST,
ARG_DETAILS,
ARG_ENV,
ARG_PREFIX,
ARG_PREFERRED,
ARG_VALID,
};
static struct option long_opts[] = {
{ "format", 1, 0, 'f' },
{ "details", 0, 0, ARG_DETAILS },
{ "env", 0, 0, ARG_ENV },
{ "prefix", 1, 0, ARG_PREFIX },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "local", 1, 0, 'a' },
@ -68,15 +151,22 @@ int main(int argc, char *argv[])
{ "peer", 1, 0, ARG_PEER },
{ "scope", 1, 0, ARG_SCOPE },
{ "broadcast", 1, 0, ARG_BROADCAST },
{ "preferred", 1, 0, ARG_PREFERRED },
{ "valid", 1, 0, ARG_VALID },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "f:hva:d:", long_opts, &optidx);
c = getopt_long(argc, argv, "46hva:d:", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case '?': exit(NLE_INVAL);
case '4': rtnl_addr_set_family(addr, AF_INET); break;
case '6': rtnl_addr_set_family(addr, AF_INET6); break;
case ARG_DETAILS: params.dp_type = NL_DUMP_DETAILS; break;
case ARG_ENV: dump_env = 1; break;
case ARG_PREFIX: prefix = strdup(optarg); break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'a': parse_local(addr, optarg); break;
@ -86,10 +176,16 @@ int main(int argc, char *argv[])
case ARG_PEER: parse_peer(addr, optarg); break;
case ARG_SCOPE: parse_scope(addr, optarg); break;
case ARG_BROADCAST: parse_broadcast(addr, optarg); break;
case ARG_PREFERRED: parse_preferred(addr, optarg); break;
case ARG_VALID: parse_valid(addr, optarg); break;
}
}
nl_cache_dump_filter(addr_cache, &params, OBJ_CAST(addr));
if (dump_env)
nl_cache_foreach_filter(addr_cache, OBJ_CAST(addr), env_dump,
&params);
else
nl_cache_dump_filter(addr_cache, &params, OBJ_CAST(addr));
return 0;
}