static int xfrm_accept_msg(const struct sockaddr_nl *who, struct rtnl_ctrl_data *ctrl, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; if (timestamp) print_timestamp(fp); if (listen_all_nsid) { if (ctrl == NULL || ctrl->nsid < 0) fprintf(fp, "[nsid current]"); else fprintf(fp, "[nsid %d]", ctrl->nsid); } switch (n->nlmsg_type) { case XFRM_MSG_NEWSA: case XFRM_MSG_DELSA: case XFRM_MSG_UPDSA: case XFRM_MSG_EXPIRE: xfrm_state_print(who, n, arg); return 0; case XFRM_MSG_NEWPOLICY: case XFRM_MSG_DELPOLICY: case XFRM_MSG_UPDPOLICY: case XFRM_MSG_POLEXPIRE: xfrm_policy_print(who, n, arg); return 0; case XFRM_MSG_ACQUIRE: xfrm_acquire_print(who, n, arg); return 0; case XFRM_MSG_FLUSHSA: xfrm_state_flush_print(who, n, arg); return 0; case XFRM_MSG_FLUSHPOLICY: xfrm_policy_flush_print(who, n, arg); return 0; case XFRM_MSG_REPORT: xfrm_report_print(who, n, arg); return 0; case XFRM_MSG_NEWAE: xfrm_ae_print(who, n, arg); return 0; case XFRM_MSG_MAPPING: xfrm_mapping_print(who, n, arg); return 0; default: break; } if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP && n->nlmsg_type != NLMSG_DONE) { fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); } return 0; }
static int xfrm_accept_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; if (timestamp) print_timestamp(fp); if (n->nlmsg_type == XFRM_MSG_NEWSA || n->nlmsg_type == XFRM_MSG_DELSA || n->nlmsg_type == XFRM_MSG_UPDSA || n->nlmsg_type == XFRM_MSG_EXPIRE) { xfrm_state_print(who, n, arg); return 0; } if (n->nlmsg_type == XFRM_MSG_NEWPOLICY || n->nlmsg_type == XFRM_MSG_DELPOLICY || n->nlmsg_type == XFRM_MSG_UPDPOLICY || n->nlmsg_type == XFRM_MSG_POLEXPIRE) { xfrm_policy_print(who, n, arg); return 0; } if (n->nlmsg_type == XFRM_MSG_ACQUIRE) { xfrm_acquire_print(who, n, arg); return 0; } if (n->nlmsg_type == XFRM_MSG_FLUSHSA) { /* XXX: Todo: show proto in xfrm_usersa_flush */ fprintf(fp, "Flushed state\n"); return 0; } if (n->nlmsg_type == XFRM_MSG_FLUSHPOLICY) { fprintf(fp, "Flushed policy\n"); return 0; } if (n->nlmsg_type == XFRM_MSG_REPORT) { xfrm_report_print(who, n, arg); return 0; } if (n->nlmsg_type == XFRM_MSG_NEWAE) { xfrm_ae_print(who, n, arg); return 0; } if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP && n->nlmsg_type != NLMSG_DONE) { fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); } return 0; }
static int xfrm_accept_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; if (timestamp) print_timestamp(fp); switch (n->nlmsg_type) { case XFRM_MSG_NEWSA: case XFRM_MSG_DELSA: case XFRM_MSG_UPDSA: case XFRM_MSG_EXPIRE: xfrm_state_print(who, n, arg); return 0; case XFRM_MSG_NEWPOLICY: case XFRM_MSG_DELPOLICY: case XFRM_MSG_UPDPOLICY: case XFRM_MSG_POLEXPIRE: xfrm_policy_print(who, n, arg); return 0; case XFRM_MSG_ACQUIRE: xfrm_acquire_print(who, n, arg); return 0; case XFRM_MSG_FLUSHSA: xfrm_state_flush_print(who, n, arg); return 0; case XFRM_MSG_FLUSHPOLICY: xfrm_policy_flush_print(who, n, arg); return 0; case XFRM_MSG_REPORT: xfrm_report_print(who, n, arg); return 0; case XFRM_MSG_NEWAE: xfrm_ae_print(who, n, arg); return 0; default: break; } if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP && n->nlmsg_type != NLMSG_DONE) { fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); } return 0; }
static int xfrm_state_allocspi(int argc, char **argv) { struct rtnl_handle rth; struct { struct nlmsghdr n; struct xfrm_userspi_info xspi; char buf[RTA_BUF_SIZE]; } req; char *idp = NULL; char *minp = NULL; char *maxp = NULL; struct xfrm_mark mark = {0, 0}; char res_buf[NLMSG_BUF_SIZE]; struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf; memset(res_buf, 0, sizeof(res_buf)); memset(&req, 0, sizeof(req)); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xspi)); req.n.nlmsg_flags = NLM_F_REQUEST; req.n.nlmsg_type = XFRM_MSG_ALLOCSPI; req.xspi.info.family = preferred_family; #if 0 req.xsinfo.lft.soft_byte_limit = XFRM_INF; req.xsinfo.lft.hard_byte_limit = XFRM_INF; req.xsinfo.lft.soft_packet_limit = XFRM_INF; req.xsinfo.lft.hard_packet_limit = XFRM_INF; #endif while (argc > 0) { if (strcmp(*argv, "mode") == 0) { NEXT_ARG(); xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv); } else if (strcmp(*argv, "mark") == 0) { xfrm_parse_mark(&mark, &argc, &argv); } else if (strcmp(*argv, "reqid") == 0) { NEXT_ARG(); xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv); } else if (strcmp(*argv, "seq") == 0) { NEXT_ARG(); xfrm_seq_parse(&req.xspi.info.seq, &argc, &argv); } else if (strcmp(*argv, "min") == 0) { if (minp) duparg("min", *argv); minp = *argv; NEXT_ARG(); if (get_u32(&req.xspi.min, *argv, 0)) invarg("\"min\" value is invalid", *argv); } else if (strcmp(*argv, "max") == 0) { if (maxp) duparg("max", *argv); maxp = *argv; NEXT_ARG(); if (get_u32(&req.xspi.max, *argv, 0)) invarg("\"max\" value is invalid", *argv); } else { /* try to assume ID */ if (idp) invarg("unknown", *argv); idp = *argv; /* ID */ xfrm_id_parse(&req.xspi.info.saddr, &req.xspi.info.id, &req.xspi.info.family, 0, &argc, &argv); if (req.xspi.info.id.spi) { fprintf(stderr, "\"SPI\" must be zero\n"); exit(1); } if (preferred_family == AF_UNSPEC) preferred_family = req.xspi.info.family; } argc--; argv++; } if (!idp) { fprintf(stderr, "Not enough information: \"ID\" is required\n"); exit(1); } if (minp) { if (!maxp) { fprintf(stderr, "\"max\" is missing\n"); exit(1); } if (req.xspi.min > req.xspi.max) { fprintf(stderr, "\"min\" value is larger than \"max\" value\n"); exit(1); } } else { if (maxp) { fprintf(stderr, "\"min\" is missing\n"); exit(1); } /* XXX: Default value defined in PF_KEY; * See kernel's net/key/af_key.c(pfkey_getspi). */ req.xspi.min = 0x100; req.xspi.max = 0x0fffffff; /* XXX: IPCOMP spi is 16-bits; * See kernel's net/xfrm/xfrm_user(verify_userspi_info). */ if (req.xspi.info.id.proto == IPPROTO_COMP) req.xspi.max = 0xffff; } if (mark.m & mark.v) { int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK, (void *)&mark, sizeof(mark)); if (r < 0) { fprintf(stderr, "XFRMA_MARK failed\n"); exit(1); } } if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) exit(1); if (req.xspi.info.family == AF_UNSPEC) req.xspi.info.family = AF_INET; if (rtnl_talk(&rth, &req.n, 0, 0, res_n) < 0) exit(2); if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) { fprintf(stderr, "An error :-)\n"); exit(1); } rtnl_close(&rth); return 0; }