📄 ipxfrm.c
字号:
case 1:
fprintf(fp, "espinudp-nonike ");
break;
case 2:
fprintf(fp, "espinudp ");
break;
default:
fprintf(fp, "%u ", e->encap_type);
break;
}
fprintf(fp, "sport %u ", ntohs(e->encap_sport));
fprintf(fp, "dport %u ", ntohs(e->encap_dport));
memset(abuf, '\0', sizeof(abuf));
fprintf(fp, "addr %s",
rt_addr_n2a(family, sizeof(e->encap_oa),
&e->encap_oa, abuf, sizeof(abuf)));
fprintf(fp, "%s", _SL_);
}
if (tb[XFRMA_TMPL]) {
struct rtattr *rta = tb[XFRMA_TMPL];
xfrm_tmpl_print((struct xfrm_user_tmpl *) RTA_DATA(rta),
RTA_PAYLOAD(rta), family, fp, prefix);
}
if (tb[XFRMA_COADDR]) {
char abuf[256];
xfrm_address_t *coa;
if (prefix)
fprintf(fp, prefix);
fprintf(fp, "coa ");
coa = (xfrm_address_t *)RTA_DATA(tb[XFRMA_COADDR]);
if (RTA_PAYLOAD(tb[XFRMA_COADDR]) < sizeof(*coa)) {
fprintf(fp, "(ERROR truncated)");
fprintf(fp, "%s", _SL_);
return;
}
memset(abuf, '\0', sizeof(abuf));
fprintf(fp, "%s",
rt_addr_n2a(family, sizeof(*coa), coa,
abuf, sizeof(abuf)));
fprintf(fp, "%s", _SL_);
}
if (tb[XFRMA_LASTUSED]) {
__u64 lastused;
if (prefix)
fprintf(fp, prefix);
fprintf(fp, "lastused ");
if (RTA_PAYLOAD(tb[XFRMA_LASTUSED]) < sizeof(lastused)) {
fprintf(fp, "(ERROR truncated)");
fprintf(fp, "%s", _SL_);
return;
}
lastused = *(__u64 *)RTA_DATA(tb[XFRMA_LASTUSED]);
fprintf(fp, "%s", strxf_time(lastused));
fprintf(fp, "%s", _SL_);
}
}
static int xfrm_selector_iszero(struct xfrm_selector *s)
{
struct xfrm_selector s0;
memset(&s0, 0, sizeof(s0));
return (memcmp(&s0, s, sizeof(s0)) == 0);
}
void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,
struct rtattr *tb[], FILE *fp, const char *prefix,
const char *title)
{
char buf[STRBUF_SIZE];
int force_spi = xfrm_xfrmproto_is_ipsec(xsinfo->id.proto);
memset(buf, '\0', sizeof(buf));
xfrm_id_info_print(&xsinfo->saddr, &xsinfo->id, xsinfo->mode,
xsinfo->reqid, xsinfo->family, force_spi, fp,
prefix, title);
if (prefix)
STRBUF_CAT(buf, prefix);
STRBUF_CAT(buf, "\t");
fprintf(fp, buf);
fprintf(fp, "replay-window %u ", xsinfo->replay_window);
if (show_stats > 0)
fprintf(fp, "seq 0x%08u ", xsinfo->seq);
if (show_stats > 0 || xsinfo->flags) {
__u8 flags = xsinfo->flags;
fprintf(fp, "flag ");
XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_NOECN, "noecn");
XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_DECAP_DSCP, "decap-dscp");
XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_WILDRECV, "wildrecv");
if (flags)
fprintf(fp, "%x", flags);
if (show_stats > 0)
fprintf(fp, " (0x%s)", strxf_mask8(flags));
}
fprintf(fp, "%s", _SL_);
xfrm_xfrma_print(tb, xsinfo->family, fp, buf);
if (!xfrm_selector_iszero(&xsinfo->sel)) {
char sbuf[STRBUF_SIZE];
memcpy(sbuf, buf, sizeof(sbuf));
STRBUF_CAT(sbuf, "sel ");
xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, sbuf);
}
if (show_stats > 0) {
xfrm_lifetime_print(&xsinfo->lft, &xsinfo->curlft, fp, buf);
xfrm_stats_print(&xsinfo->stats, fp, buf);
}
}
void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo,
struct rtattr *tb[], FILE *fp, const char *prefix,
const char *title)
{
char buf[STRBUF_SIZE];
__u8 ptype = XFRM_POLICY_TYPE_MAIN;
memset(buf, '\0', sizeof(buf));
xfrm_selector_print(&xpinfo->sel, preferred_family, fp, title);
if (prefix)
STRBUF_CAT(buf, prefix);
STRBUF_CAT(buf, "\t");
fprintf(fp, buf);
fprintf(fp, "dir ");
switch (xpinfo->dir) {
case XFRM_POLICY_IN:
fprintf(fp, "in");
break;
case XFRM_POLICY_OUT:
fprintf(fp, "out");
break;
case XFRM_POLICY_FWD:
fprintf(fp, "fwd");
break;
default:
fprintf(fp, "%u", xpinfo->dir);
break;
}
fprintf(fp, " ");
switch (xpinfo->action) {
case XFRM_POLICY_ALLOW:
if (show_stats > 0)
fprintf(fp, "action allow ");
break;
case XFRM_POLICY_BLOCK:
fprintf(fp, "action block ");
break;
default:
fprintf(fp, "action %u ", xpinfo->action);
break;
}
if (show_stats)
fprintf(fp, "index %u ", xpinfo->index);
fprintf(fp, "priority %u ", xpinfo->priority);
fprintf(fp, "ptype ");
if (tb[XFRMA_POLICY_TYPE]) {
struct xfrm_userpolicy_type *upt;
if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt))
fprintf(fp, "(ERROR truncated)");
upt = (struct xfrm_userpolicy_type *)RTA_DATA(tb[XFRMA_POLICY_TYPE]);
ptype = upt->type;
}
switch (ptype) {
case XFRM_POLICY_TYPE_MAIN:
fprintf(fp, "main");
break;
case XFRM_POLICY_TYPE_SUB:
fprintf(fp, "sub");
break;
default:
fprintf(fp, "%u", ptype);
break;
}
fprintf(fp, " ");
if (show_stats > 0) {
fprintf(fp, "share %s ", strxf_share(xpinfo->share));
fprintf(fp, "flag 0x%s", strxf_mask8(xpinfo->flags));
}
fprintf(fp, "%s", _SL_);
if (show_stats > 0)
xfrm_lifetime_print(&xpinfo->lft, &xpinfo->curlft, fp, buf);
xfrm_xfrma_print(tb, xpinfo->sel.family, fp, buf);
}
int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family,
int loose, int *argcp, char ***argvp)
{
int argc = *argcp;
char **argv = *argvp;
inet_prefix dst;
inet_prefix src;
memset(&dst, 0, sizeof(dst));
memset(&src, 0, sizeof(src));
while (1) {
if (strcmp(*argv, "src") == 0) {
NEXT_ARG();
get_prefix(&src, *argv, preferred_family);
if (src.family == AF_UNSPEC)
invarg("\"src\" address family is AF_UNSPEC", *argv);
if (family)
*family = src.family;
memcpy(saddr, &src.data, sizeof(*saddr));
filter.id_src_mask = src.bitlen;
} else if (strcmp(*argv, "dst") == 0) {
NEXT_ARG();
get_prefix(&dst, *argv, preferred_family);
if (dst.family == AF_UNSPEC)
invarg("\"dst\" address family is AF_UNSPEC", *argv);
if (family)
*family = dst.family;
memcpy(&id->daddr, &dst.data, sizeof(id->daddr));
filter.id_dst_mask = dst.bitlen;
} else if (strcmp(*argv, "proto") == 0) {
int ret;
NEXT_ARG();
ret = xfrm_xfrmproto_getbyname(*argv);
if (ret < 0)
invarg("\"XFRM_PROTO\" is invalid", *argv);
id->proto = (__u8)ret;
filter.id_proto_mask = XFRM_FILTER_MASK_FULL;
} else if (strcmp(*argv, "spi") == 0) {
__u32 spi;
NEXT_ARG();
if (get_u32(&spi, *argv, 0))
invarg("\"SPI\" is invalid", *argv);
spi = htonl(spi);
id->spi = spi;
filter.id_spi_mask = XFRM_FILTER_MASK_FULL;
} else {
PREV_ARG(); /* back track */
break;
}
if (!NEXT_ARG_OK())
break;
NEXT_ARG();
}
if (src.family && dst.family && (src.family != dst.family))
invarg("the same address family is required between \"src\" and \"dst\"", *argv);
if (loose == 0 && id->proto == 0)
missarg("XFRM_PROTO");
if (argc == *argcp)
missarg("ID");
*argcp = argc;
*argvp = argv;
return 0;
}
int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp)
{
int argc = *argcp;
char **argv = *argvp;
if (matches(*argv, "transport") == 0)
*mode = XFRM_MODE_TRANSPORT;
else if (matches(*argv, "tunnel") == 0)
*mode = XFRM_MODE_TUNNEL;
else if (matches(*argv, "ro") == 0)
*mode = XFRM_MODE_ROUTEOPTIMIZATION;
else if (matches(*argv, "in_trigger") == 0)
*mode = XFRM_MODE_IN_TRIGGER;
else if (matches(*argv, "beet") == 0)
*mode = XFRM_MODE_BEET;
else
invarg("\"MODE\" is invalid", *argv);
*argcp = argc;
*argvp = argv;
return 0;
}
int xfrm_encap_type_parse(__u16 *type, int *argcp, char ***argvp)
{
int argc = *argcp;
char **argv = *argvp;
if (strcmp(*argv, "espinudp-nonike") == 0)
*type = 1;
else if (strcmp(*argv, "espinudp") == 0)
*type = 2;
else
invarg("\"ENCAP-TYPE\" is invalid", *argv);
*argcp = argc;
*argvp = argv;
return 0;
}
/* NOTE: reqid is used by host-byte order */
int xfrm_reqid_parse(__u32 *reqid, int *argcp, char ***argvp)
{
int argc = *argcp;
char **argv = *argvp;
if (get_u32(reqid, *argv, 0))
invarg("\"REQID\" is invalid", *argv);
*argcp = argc;
*argvp = argv;
return 0;
}
static int xfrm_selector_upspec_parse(struct xfrm_selector *sel,
int *argcp, char ***argvp)
{
int argc = *argcp;
char **argv = *argvp;
char *sportp = NULL;
char *dportp = NULL;
char *typep = NULL;
char *codep = NULL;
while (1) {
if (strcmp(*argv, "proto") == 0) {
__u8 upspec;
NEXT_ARG();
if (strcmp(*argv, "any") == 0)
upspec = 0;
else {
struct protoent *pp;
pp = getprotobyname(*argv);
if (pp)
upspec = pp->p_proto;
else {
if (get_u8(&upspec, *argv, 0))
invarg("\"PROTO\" is invalid", *argv);
}
}
sel->proto = upspec;
filter.upspec_proto_mask = XFRM_FILTER_MASK_FULL;
} else if (strcmp(*argv, "sport") == 0) {
sportp = *argv;
NEXT_ARG();
if (get_u16(&sel->sport, *argv, 0))
invarg("\"PORT\" is invalid", *argv);
sel->sport = htons(sel->sport);
if (sel->sport)
sel->sport_mask = ~((__u16)0);
filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL;
} else if (strcmp(*argv, "dport") == 0) {
dportp = *argv;
NEXT_ARG();
if (get_u16(&sel->dport, *argv, 0))
invarg("\"PORT\" is invalid", *argv);
sel->dport = htons(sel->dport);
if (sel->dport)
sel->dport_mask = ~((__u16)0);
filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL;
} else if (strcmp(*argv, "type") == 0) {
typep = *argv;
NEXT_ARG();
if (get_u16(&sel->sport, *argv, 0) ||
(sel->sport & ~((__u16)0xff)))
invarg("\"type\" value is invalid", *argv);
sel->sport = htons(sel->sport);
sel->sport_mask = ~((__u16)0);
filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL;
} else if (strcmp(*argv, "code") == 0) {
codep = *argv;
NEXT_ARG();
if (get_u16(&sel->dport, *argv, 0) ||
(sel->dport & ~((__u16)0xff)))
invarg("\"code\" value is invalid", *argv);
sel->dport = htons(sel->dport);
sel->dport_mask = ~((__u16)0);
filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL;
} else {
PREV_ARG(); /* back track */
break;
}
if (!NEXT_ARG_OK())
break;
NEXT_ARG();
}
if (argc == *argcp)
missarg("UPSPEC");
if (sportp || dportp) {
switch (sel->proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
break;
default:
fprintf(stderr, "\"sport\" and \"dport\" are invalid with proto=%s\n", strxf_proto(sel->proto));
exit(1);
}
}
if (typep || codep) {
switch (sel->proto) {
case IPPROTO_ICMP:
case IPPROTO_ICMPV6:
case IPPROTO_MH:
break;
default:
fprintf(stderr, "\"type\" and \"code\" are invalid with proto=%s\n", strxf_proto(sel->proto));
exit(1);
}
}
*argcp = argc;
*argvp = argv;
return 0;
}
int xfrm_selector_parse(struct xfrm_selector *sel, int *argcp, char ***argvp)
{
int argc = *argcp;
char **argv = *argvp;
inet_prefix dst;
inet_prefix src;
char *upspecp = NULL;
memset(&dst, 0, sizeof(dst));
memset(&src, 0, sizeof(src));
while (1) {
if (strcmp(*argv, "src") == 0) {
NEXT_ARG();
get_prefix(&src, *argv, preferred_family);
if (src.family == AF_UNSPEC)
invarg("\"src\" address family is AF_UNSPEC", *argv);
sel->family = src.family;
memcpy(&sel->saddr, &src.data, sizeof(sel->saddr));
sel->prefixlen_s = src.bitlen;
filter.sel_src_mask = src.bitlen;
} else if (strcmp(*argv, "dst") == 0) {
NEXT_ARG();
get_prefix(&dst, *argv, preferred_family);
if (dst.family == AF_UNSPEC)
invarg("\"dst\" address family is AF_UNSPEC", *argv);
sel->family = dst.family;
memcpy(&sel->daddr, &dst.data, sizeof(sel->daddr));
sel->prefixlen_d = dst.bitlen;
filter.sel_dst_mask = dst.bitlen;
} else if (strcmp(*argv, "dev") == 0) {
int ifindex;
NEXT_ARG();
if (strcmp(*argv, "none") == 0)
ifindex = 0;
else {
ifindex = if_nametoindex(*argv);
if (ifindex <= 0)
invarg("\"DEV\" is invalid", *argv);
}
sel->ifindex = ifindex;
filter.sel_dev_mask = XFRM_FILTER_MASK_FULL;
} else {
if (upspecp) {
PREV_ARG(); /* back track */
break;
} else {
upspecp = *argv;
xfrm_selector_upspec_parse(sel, &argc, &argv);
}
}
if (!NEXT_ARG_OK())
break;
NEXT_ARG();
}
if (src.family && dst.family && (src.family != dst.family))
invarg("the same address family is required between \"src\" and \"dst\"", *argv);
if (argc == *argcp)
missarg("SELECTOR");
*argcp = argc;
*argvp = argv;
return 0;
}
int xfrm_lifetime_cfg_parse(struct xfrm_lifetime_cfg *lft,
int *argcp, char ***argvp)
{
int argc = *argcp;
char **argv = *argvp;
int ret;
if (strcmp(*argv, "time-soft") == 0) {
NEXT_ARG();
ret = get_u64(&lft->soft_add_expires_seconds, *argv, 0);
if (ret)
invarg("\"time-soft\" value is invalid", *argv);
} else if (strcmp(*argv, "time-hard") == 0) {
NEXT_ARG();
ret = get_u64(&lft->hard_add_expires_seconds, *argv, 0);
if (ret)
invarg("\"time-hard\" value is invalid", *argv);
} else if (strcmp(*argv, "time-use-soft") == 0) {
NEXT_ARG();
ret = get_u64(&lft->soft_use_expires_seconds, *argv, 0);
if (ret)
invarg("\"time-use-soft\" value is invalid", *argv);
} else if (strcmp(*argv, "time-use-hard") == 0) {
NEXT_ARG();
ret = get_u64(&lft->hard_use_expires_seconds, *argv, 0);
if (ret)
invarg("\"time-use-hard\" value is invalid", *argv);
} else if (strcmp(*argv, "byte-soft") == 0) {
NEXT_ARG();
ret = get_u64(&lft->soft_byte_limit, *argv, 0);
if (ret)
invarg("\"byte-soft\" value is invalid", *argv);
} else if (strcmp(*argv, "byte-hard") == 0) {
NEXT_ARG();
ret = get_u64(&lft->hard_byte_limit, *argv, 0);
if (ret)
invarg("\"byte-hard\" value is invalid", *argv);
} else if (strcmp(*argv, "packet-soft") == 0) {
NEXT_ARG();
ret = get_u64(&lft->soft_packet_limit, *argv, 0);
if (ret)
invarg("\"packet-soft\" value is invalid", *argv);
} else if (strcmp(*argv, "packet-hard") == 0) {
NEXT_ARG();
ret = get_u64(&lft->hard_packet_limit, *argv, 0);
if (ret)
invarg("\"packet-hard\" value is invalid", *argv);
} else
invarg("\"LIMIT\" is invalid", *argv);
*argcp = argc;
*argvp = argv;
return 0;
}
int do_xfrm(int argc, char **argv)
{
memset(&filter, 0, sizeof(filter));
if (argc < 1)
usage();
if (matches(*argv, "state") == 0 ||
matches(*argv, "sa") == 0)
return do_xfrm_state(argc-1, argv+1);
else if (matches(*argv, "policy") == 0)
return do_xfrm_policy(argc-1, argv+1);
else if (matches(*argv, "monitor") == 0)
return do_xfrm_monitor(argc-1, argv+1);
else if (matches(*argv, "help") == 0) {
usage();
fprintf(stderr, "xfrm Object \"%s\" is unknown.\n", *argv);
exit(-1);
}
usage();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -