📄 ipntable.c
字号:
/*
* Copyright (C)2006 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 ipneigh.c
*/
/*
* Authors:
* Masahide NAKAMURA @USAGI
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "utils.h"
#include "ip_common.h"
static struct
{
int family;
int index;
#define NONE_DEV (-1)
char name[1024];
} filter;
static void usage(void) __attribute__((noreturn));
static void usage(void)
{
fprintf(stderr,
"Usage: ip ntable change name NAME [ dev DEV ]\n"
" [ thresh1 VAL ] [ thresh2 VAL ] [ thresh3 VAL ] [ gc_int MSEC ]\n"
" [ PARMS ]\n"
"Usage: ip ntable show [ dev DEV ] [ name NAME ]\n"
"PARMS := [ base_reachable MSEC ] [ retrans MSEC ] [ gc_stale MSEC ]\n"
" [ delay_probe MSEC ] [ queue LEN ]\n"
" [ app_probs VAL ] [ ucast_probes VAL ] [ mcast_probes VAL ]\n"
" [ anycast_delay MSEC ] [ proxy_delay MSEC ] [ proxy_queue LEN ]\n"
" [ locktime MSEC ]\n"
);
exit(-1);
}
static int ipntable_modify(int cmd, int flags, int argc, char **argv)
{
struct {
struct nlmsghdr n;
struct ndtmsg ndtm;
char buf[1024];
} req;
char *namep = NULL;
char *threshsp = NULL;
char *gc_intp = NULL;
char parms_buf[1024];
struct rtattr *parms_rta = (struct rtattr *)parms_buf;
int parms_change = 0;
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndtmsg));
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
req.n.nlmsg_type = cmd;
req.ndtm.ndtm_family = preferred_family;
req.ndtm.ndtm_pad1 = 0;
req.ndtm.ndtm_pad2 = 0;
memset(&parms_buf, 0, sizeof(parms_buf));
parms_rta->rta_type = NDTA_PARMS;
parms_rta->rta_len = RTA_LENGTH(0);
while (argc > 0) {
if (strcmp(*argv, "name") == 0) {
int len;
NEXT_ARG();
if (namep)
duparg("NAME", *argv);
namep = *argv;
len = strlen(namep) + 1;
addattr_l(&req.n, sizeof(req), NDTA_NAME, namep, len);
} else if (strcmp(*argv, "thresh1") == 0) {
__u32 thresh1;
NEXT_ARG();
threshsp = *argv;
if (get_u32(&thresh1, *argv, 0))
invarg("\"thresh1\" value is invalid", *argv);
addattr32(&req.n, sizeof(req), NDTA_THRESH1, thresh1);
} else if (strcmp(*argv, "thresh2") == 0) {
__u32 thresh2;
NEXT_ARG();
threshsp = *argv;
if (get_u32(&thresh2, *argv, 0))
invarg("\"thresh2\" value is invalid", *argv);
addattr32(&req.n, sizeof(req), NDTA_THRESH2, thresh2);
} else if (strcmp(*argv, "thresh3") == 0) {
__u32 thresh3;
NEXT_ARG();
threshsp = *argv;
if (get_u32(&thresh3, *argv, 0))
invarg("\"thresh3\" value is invalid", *argv);
addattr32(&req.n, sizeof(req), NDTA_THRESH3, thresh3);
} else if (strcmp(*argv, "gc_int") == 0) {
__u64 gc_int;
NEXT_ARG();
gc_intp = *argv;
if (get_u64(&gc_int, *argv, 0))
invarg("\"gc_int\" value is invalid", *argv);
addattr_l(&req.n, sizeof(req), NDTA_GC_INTERVAL,
&gc_int, sizeof(gc_int));
} else if (strcmp(*argv, "dev") == 0) {
__u32 ifindex;
NEXT_ARG();
ifindex = ll_name_to_index(*argv);
if (ifindex == 0) {
fprintf(stderr, "Cannot find device \"%s\"\n", *argv);
return -1;
}
rta_addattr32(parms_rta, sizeof(parms_buf),
NDTPA_IFINDEX, ifindex);
} else if (strcmp(*argv, "base_reachable") == 0) {
__u64 breachable;
NEXT_ARG();
if (get_u64(&breachable, *argv, 0))
invarg("\"base_reachable\" value is invalid", *argv);
rta_addattr_l(parms_rta, sizeof(parms_buf),
NDTPA_BASE_REACHABLE_TIME,
&breachable, sizeof(breachable));
parms_change = 1;
} else if (strcmp(*argv, "retrans") == 0) {
__u64 retrans;
NEXT_ARG();
if (get_u64(&retrans, *argv, 0))
invarg("\"retrans\" value is invalid", *argv);
rta_addattr_l(parms_rta, sizeof(parms_buf),
NDTPA_RETRANS_TIME,
&retrans, sizeof(retrans));
parms_change = 1;
} else if (strcmp(*argv, "gc_stale") == 0) {
__u64 gc_stale;
NEXT_ARG();
if (get_u64(&gc_stale, *argv, 0))
invarg("\"gc_stale\" value is invalid", *argv);
rta_addattr_l(parms_rta, sizeof(parms_buf),
NDTPA_GC_STALETIME,
&gc_stale, sizeof(gc_stale));
parms_change = 1;
} else if (strcmp(*argv, "delay_probe") == 0) {
__u64 delay_probe;
NEXT_ARG();
if (get_u64(&delay_probe, *argv, 0))
invarg("\"delay_probe\" value is invalid", *argv);
rta_addattr_l(parms_rta, sizeof(parms_buf),
NDTPA_DELAY_PROBE_TIME,
&delay_probe, sizeof(delay_probe));
parms_change = 1;
} else if (strcmp(*argv, "queue") == 0) {
__u32 queue;
NEXT_ARG();
if (get_u32(&queue, *argv, 0))
invarg("\"queue\" value is invalid", *argv);
if (!parms_rta)
parms_rta = (struct rtattr *)&parms_buf;
rta_addattr32(parms_rta, sizeof(parms_buf),
NDTPA_QUEUE_LEN, queue);
parms_change = 1;
} else if (strcmp(*argv, "app_probes") == 0) {
__u32 aprobe;
NEXT_ARG();
if (get_u32(&aprobe, *argv, 0))
invarg("\"app_probes\" value is invalid", *argv);
rta_addattr32(parms_rta, sizeof(parms_buf),
NDTPA_APP_PROBES, aprobe);
parms_change = 1;
} else if (strcmp(*argv, "ucast_probes") == 0) {
__u32 uprobe;
NEXT_ARG();
if (get_u32(&uprobe, *argv, 0))
invarg("\"ucast_probes\" value is invalid", *argv);
rta_addattr32(parms_rta, sizeof(parms_buf),
NDTPA_UCAST_PROBES, uprobe);
parms_change = 1;
} else if (strcmp(*argv, "mcast_probes") == 0) {
__u32 mprobe;
NEXT_ARG();
if (get_u32(&mprobe, *argv, 0))
invarg("\"mcast_probes\" value is invalid", *argv);
rta_addattr32(parms_rta, sizeof(parms_buf),
NDTPA_MCAST_PROBES, mprobe);
parms_change = 1;
} else if (strcmp(*argv, "anycast_delay") == 0) {
__u64 anycast_delay;
NEXT_ARG();
if (get_u64(&anycast_delay, *argv, 0))
invarg("\"anycast_delay\" value is invalid", *argv);
rta_addattr_l(parms_rta, sizeof(parms_buf),
NDTPA_ANYCAST_DELAY,
&anycast_delay, sizeof(anycast_delay));
parms_change = 1;
} else if (strcmp(*argv, "proxy_delay") == 0) {
__u64 proxy_delay;
NEXT_ARG();
if (get_u64(&proxy_delay, *argv, 0))
invarg("\"proxy_delay\" value is invalid", *argv);
rta_addattr_l(parms_rta, sizeof(parms_buf),
NDTPA_PROXY_DELAY,
&proxy_delay, sizeof(proxy_delay));
parms_change = 1;
} else if (strcmp(*argv, "proxy_queue") == 0) {
__u32 pqueue;
NEXT_ARG();
if (get_u32(&pqueue, *argv, 0))
invarg("\"proxy_queue\" value is invalid", *argv);
rta_addattr32(parms_rta, sizeof(parms_buf),
NDTPA_PROXY_QLEN, pqueue);
parms_change = 1;
} else if (strcmp(*argv, "locktime") == 0) {
__u64 locktime;
NEXT_ARG();
if (get_u64(&locktime, *argv, 0))
invarg("\"locktime\" value is invalid", *argv);
rta_addattr_l(parms_rta, sizeof(parms_buf),
NDTPA_LOCKTIME,
&locktime, sizeof(locktime));
parms_change = 1;
} else {
invarg("unknown", *argv);
}
argc--; argv++;
}
if (!namep)
missarg("NAME");
if (!threshsp && !gc_intp && !parms_change) {
fprintf(stderr, "Not enough information: changable attributes required.\n");
exit(-1);
}
if (parms_rta->rta_len > RTA_LENGTH(0)) {
addattr_l(&req.n, sizeof(req), NDTA_PARMS, RTA_DATA(parms_rta),
RTA_PAYLOAD(parms_rta));
}
if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
exit(2);
return 0;
}
static const char *ntable_strtime_delta(__u32 msec)
{
static char str[32];
struct timeval now;
time_t t;
struct tm *tp;
if (msec == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -