diff options
author | net[shemminger]!shemminger <net[shemminger]!shemminger> | 2005-01-17 23:30:18 +0000 |
---|---|---|
committer | net[shemminger]!shemminger <net[shemminger]!shemminger> | 2005-01-17 23:30:18 +0000 |
commit | 1cb54e58069fb413bd20738754b4e49f0403da0c (patch) | |
tree | 9936fe53386fe0c80f8e107232f817b3bd526079 /ip | |
parent | ab3887d6c9354b569aa0878c8028a55f296464af (diff) |
Import patch iproute2.118
(Logical change 1.120)
Diffstat (limited to 'ip')
-rw-r--r-- | ip/Makefile | 2 | ||||
-rw-r--r-- | ip/ip_common.h | 2 | ||||
-rw-r--r-- | ip/ipmonitor.c | 12 | ||||
-rw-r--r-- | ip/ipprefix.c | 107 |
4 files changed, 122 insertions, 1 deletions
diff --git a/ip/Makefile b/ip/Makefile index d1378c77..a1326d12 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -1,6 +1,6 @@ IPOBJ=ip.o ipaddress.o iproute.o iprule.o \ rtm_map.o iptunnel.o ipneigh.o iplink.o \ - ipmaddr.o ipmonitor.o ipmroute.o \ + ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o \ ipxfrm.o xfrm_state.o xfrm_policy.o RTMONOBJ=rtmon.o diff --git a/ip/ip_common.h b/ip/ip_common.h index 93ac3f9f..688d384c 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -15,6 +15,8 @@ extern void ipaddr_reset_filter(int); extern void ipneigh_reset_filter(void); extern int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); +extern int print_prefix(const struct sockaddr_nl *who, + struct nlmsghdr *n, void *arg); extern int do_ipaddr(int argc, char **argv); extern int do_iproute(int argc, char **argv); extern int do_iprule(int argc, char **argv); diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c index 7f5041a7..cdaeb6f9 100644 --- a/ip/ipmonitor.c +++ b/ip/ipmonitor.c @@ -55,6 +55,10 @@ int accept_msg(const struct sockaddr_nl *who, print_neigh(who, n, arg); return 0; } + if (n->nlmsg_type == RTM_NEWPREFIX) { + print_prefix(who, n, arg); + return 0; + } if (n->nlmsg_type == 15) { char *tstr; time_t secs = ((__u32*)NLMSG_DATA(n))[0]; @@ -87,6 +91,7 @@ int do_ipmonitor(int argc, char **argv) int llink=0; int laddr=0; int lroute=0; + int lprefix=0; ipaddr_reset_filter(1); iproute_reset_filter(); @@ -105,6 +110,9 @@ int do_ipmonitor(int argc, char **argv) } else if (matches(*argv, "route") == 0) { lroute=1; groups = 0; + } else if (matches(*argv, "prefix") == 0) { + lprefix=1; + groups = 0; } else if (strcmp(*argv, "all") == 0) { groups = ~RTMGRP_TC; } else if (matches(*argv, "help") == 0) { @@ -130,6 +138,10 @@ int do_ipmonitor(int argc, char **argv) if (!preferred_family || preferred_family == AF_INET6) groups |= RTMGRP_IPV6_ROUTE; } + if (lprefix) { + if (!preferred_family || preferred_family == AF_INET6) + groups |= RTMGRP_IPV6_PREFIX; + } if (file) { FILE *fp; diff --git a/ip/ipprefix.c b/ip/ipprefix.c index e69de29b..6fd39afc 100644 --- a/ip/ipprefix.c +++ b/ip/ipprefix.c @@ -0,0 +1,107 @@ +/* + * Copyright (C)2005 USAGI/WIDE Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * based on ip.c, iproute.c + */ +/* + * Authors: + * Masahide NAKAMURA @USAGI + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netinet/icmp6.h> +#include "utils.h" + +/* prefix flags; see kernel's net/ipv6/addrconf.c and include/net/if_inet6.h */ +#define IF_PREFIX_ONLINK 0x01 +#define IF_PREFIX_AUTOCONF 0x02 + +int print_prefix(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) +{ + FILE *fp = (FILE*)arg; + struct prefixmsg *prefix = NLMSG_DATA(n); + int len = n->nlmsg_len; + struct rtattr * tb[RTA_MAX+1]; + int family = preferred_family; + + if (n->nlmsg_type != RTM_NEWPREFIX) { + fprintf(stderr, "Not a prefix: %08x %08x %08x\n", + n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); + return 0; + } + + len -= NLMSG_LENGTH(sizeof(*prefix)); + if (len < 0) { + fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); + return -1; + } + + if (family == AF_UNSPEC) + family = AF_INET6; + if (family != AF_INET6) + return 0; + + if (prefix->prefix_family != AF_INET6) { + fprintf(stderr, "wrong family %d\n", prefix->prefix_family); + return 0; + } + if (prefix->prefix_type != ND_OPT_PREFIX_INFORMATION) { + fprintf(stderr, "wrong ND type %d\n", prefix->prefix_type); + return 0; + } + + memset(tb, 0, sizeof(tb)); + parse_rtattr(tb, RTA_MAX, RTM_RTA(prefix), len); + + fprintf(fp, "prefix "); + + if (tb[PREFIX_ADDRESS]) { + struct in6_addr *pfx; + char abuf[256]; + + pfx = (struct in6_addr *)RTA_DATA(tb[PREFIX_ADDRESS]); + + memset(abuf, '\0', sizeof(abuf)); + fprintf(fp, "%s", rt_addr_n2a(family, sizeof(*pfx), pfx, + abuf, sizeof(abuf))); + } + fprintf(fp, "/%u ", prefix->prefix_len); + + fprintf(fp, "dev %s ", ll_index_to_name(prefix->prefix_ifindex)); + + if (prefix->prefix_flags & IF_PREFIX_ONLINK) + fprintf(fp, "onlink "); + if (prefix->prefix_flags & IF_PREFIX_AUTOCONF) + fprintf(fp, "autoconf "); + + if (tb[PREFIX_CACHEINFO]) { + struct prefix_cacheinfo *pc; + pc = (struct prefix_cacheinfo *)tb[PREFIX_CACHEINFO]; + + fprintf(fp, "valid %u ", pc->valid_time); + fprintf(fp, "preferred %u ", pc->preferred_time); + } + + fprintf(fp, "\n"); + fflush(fp); + + return 0; +} + |