static int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback) { uint32_t flags = NLM_F_REQUEST | NLM_F_ACK; uint32_t seq; int ret; if (command != RDMA_NLDEV_CMD_RES_GET) flags |= NLM_F_DUMP; rd_prepare_msg(rd, command, &seq, flags); mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); if (rd->port_idx) mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx); ret = rd_send_msg(rd); if (ret) return ret; if (rd->json_output) jsonw_start_object(rd->jw); ret = rd_recv_msg(rd, callback, rd, seq); if (rd->json_output) jsonw_end_object(rd->jw); return ret; }
static void nft_rule_expr_byteorder_build(struct nlmsghdr *nlh, struct nft_rule_expr *e) { struct nft_expr_byteorder *byteorder = nft_expr_data(e); if (e->flags & (1 << NFT_EXPR_BYTEORDER_SREG)) { mnl_attr_put_u32(nlh, NFTA_BYTEORDER_SREG, htonl(byteorder->sreg)); } if (e->flags & (1 << NFT_EXPR_BYTEORDER_DREG)) { mnl_attr_put_u32(nlh, NFTA_BYTEORDER_DREG, htonl(byteorder->dreg)); } if (e->flags & (1 << NFT_EXPR_BYTEORDER_OP)) { mnl_attr_put_u32(nlh, NFTA_BYTEORDER_OP, htonl(byteorder->op)); } if (e->flags & (1 << NFT_EXPR_BYTEORDER_LEN)) { mnl_attr_put_u32(nlh, NFTA_BYTEORDER_LEN, htonl(byteorder->len)); } if (e->flags & (1 << NFT_EXPR_BYTEORDER_SIZE)) { mnl_attr_put_u32(nlh, NFTA_BYTEORDER_SIZE, htonl(byteorder->size)); } }
static void nft_rule_expr_bitwise_build(struct nlmsghdr *nlh, struct nft_rule_expr *e) { struct nft_expr_bitwise *bitwise = nft_expr_data(e); if (e->flags & (1 << NFT_EXPR_BITWISE_SREG)) mnl_attr_put_u32(nlh, NFTA_BITWISE_SREG, htonl(bitwise->sreg)); if (e->flags & (1 << NFT_EXPR_BITWISE_DREG)) mnl_attr_put_u32(nlh, NFTA_BITWISE_DREG, htonl(bitwise->dreg)); if (e->flags & (1 << NFT_EXPR_BITWISE_LEN)) mnl_attr_put_u32(nlh, NFTA_BITWISE_LEN, htonl(bitwise->len)); if (e->flags & (1 << NFT_EXPR_BITWISE_MASK)) { struct nlattr *nest; nest = mnl_attr_nest_start(nlh, NFTA_BITWISE_MASK); mnl_attr_put(nlh, NFTA_DATA_VALUE, bitwise->mask.len, bitwise->mask.val); mnl_attr_nest_end(nlh, nest); } if (e->flags & (1 << NFT_EXPR_BITWISE_XOR)) { struct nlattr *nest; nest = mnl_attr_nest_start(nlh, NFTA_BITWISE_XOR); mnl_attr_put(nlh, NFTA_DATA_VALUE, bitwise->xor.len, bitwise->xor.val); mnl_attr_nest_end(nlh, nest); } }
static int nfct_build_tuple_ip(struct nlmsghdr *nlh, const struct __nfct_tuple *t) { struct nlattr *nest; nest = mnl_attr_nest_start(nlh, CTA_TUPLE_IP); if (nest == NULL) return -1; switch(t->l3protonum) { case AF_INET: mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, t->src.v4); mnl_attr_put_u32(nlh, CTA_IP_V4_DST, t->dst.v4); break; case AF_INET6: mnl_attr_put(nlh, CTA_IP_V6_SRC, sizeof(struct in6_addr), &t->src.v6); mnl_attr_put(nlh, CTA_IP_V6_DST, sizeof(struct in6_addr), &t->dst.v6); break; default: mnl_attr_nest_cancel(nlh, nest); return -1; } mnl_attr_nest_end(nlh, nest); return 0; }
static int nfct_nat_seq_adj(struct nlmsghdr *nlh, const struct nf_conntrack *ct, int dir) { mnl_attr_put_u32(nlh, CTA_NAT_SEQ_CORRECTION_POS, htonl(ct->natseq[dir].correction_pos)); mnl_attr_put_u32(nlh, CTA_NAT_SEQ_OFFSET_BEFORE, htonl(ct->natseq[dir].offset_before)); mnl_attr_put_u32(nlh, CTA_NAT_SEQ_OFFSET_AFTER, htonl(ct->natseq[dir].offset_after)); return 0; }
static void nftnl_expr_payload_build(struct nlmsghdr *nlh, struct nftnl_expr *e) { struct nftnl_expr_payload *payload = nftnl_expr_data(e); if (e->flags & (1 << NFTNL_EXPR_PAYLOAD_DREG)) mnl_attr_put_u32(nlh, NFTA_PAYLOAD_DREG, htonl(payload->dreg)); if (e->flags & (1 << NFTNL_EXPR_PAYLOAD_BASE)) mnl_attr_put_u32(nlh, NFTA_PAYLOAD_BASE, htonl(payload->base)); if (e->flags & (1 << NFTNL_EXPR_PAYLOAD_OFFSET)) mnl_attr_put_u32(nlh, NFTA_PAYLOAD_OFFSET, htonl(payload->offset)); if (e->flags & (1 << NFTNL_EXPR_PAYLOAD_LEN)) mnl_attr_put_u32(nlh, NFTA_PAYLOAD_LEN, htonl(payload->len)); }
static void nft_rule_expr_ct_build(struct nlmsghdr *nlh, struct nft_rule_expr *e) { struct nft_expr_ct *ct = nft_expr_data(e); if (e->flags & (1 << NFT_EXPR_CT_KEY)) mnl_attr_put_u32(nlh, NFTA_CT_KEY, htonl(ct->key)); if (e->flags & (1 << NFT_EXPR_CT_DREG)) mnl_attr_put_u32(nlh, NFTA_CT_DREG, htonl(ct->dreg)); if (e->flags & (1 << NFT_EXPR_CT_DIR)) mnl_attr_put_u8(nlh, NFTA_CT_DIRECTION, ct->dir); if (e->flags & (1 << NFT_EXPR_CT_SREG)) mnl_attr_put_u32(nlh, NFTA_CT_SREG, htonl(ct->sreg)); }
/* Adds/deletes route. The reason for having metric as a seperate parameter is * that the value depends on wether this is the private table (0) or not. If the * route is intended for the private table, then ignore metric */ static int32_t multi_link_modify_route(uint32_t msg_type, uint32_t flags, uint32_t table_id, struct multi_link_info *li, uint32_t metric){ uint8_t buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct rtmsg *rt; uint32_t nw_ip = 0; //The desired destination IP is store in different places for PPP and //"normal" interfaces. This is the network route! if(li->state == GOT_IP_PPP || li->state == LINK_UP_PPP) nw_ip = li->cfg.broadcast.s_addr; else nw_ip = li->cfg.address.s_addr & li->cfg.netmask.s_addr; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = msg_type; nlh->nlmsg_flags = NLM_F_REQUEST | flags; nlh->nlmsg_seq = 0; rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg)); rt->rtm_scope = RT_SCOPE_NOWHERE; rt->rtm_type = RTN_UNICAST; rt->rtm_family = AF_INET; rt->rtm_dst_len = 32 - (ffs(ntohl(li->cfg.netmask.s_addr)) - 1); rt->rtm_table = table_id; if(msg_type != RTM_DELROUTE){ rt->rtm_protocol = RTPROT_BOOT; rt->rtm_scope = RT_SCOPE_LINK; } mnl_attr_put_u32(nlh, RTA_DST, nw_ip); mnl_attr_put_u32(nlh, RTA_PREFSRC, li->cfg.address.s_addr); mnl_attr_put_u32(nlh, RTA_OIF, li->ifi_idx); if(metric) mnl_attr_put_u32(nlh, RTA_PRIORITY, metric); if(mnl_socket_sendto(multi_link_nl_set, nlh, nlh->nlmsg_len) < 0){ MULTI_DEBUG_PRINT(stderr,"Could not send private route to kernel " "(can be ignored if caused by an interface that went down, " "iface idx %u)\n", li->ifi_idx); return -1; } return 0; }
static int cmd_link_mon_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, void *data) { int size; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlattr *attrs; if (cmdl->argc != cmdl->optind + 1) { fprintf(stderr, "error, missing value\n"); return -EINVAL; } size = atoi(shift_cmdl(cmdl)); nlh = msg_init(buf, TIPC_NL_MON_SET); if (!nlh) { fprintf(stderr, "error, message initialisation failed\n"); return -1; } attrs = mnl_attr_nest_start(nlh, TIPC_NLA_MON); mnl_attr_put_u32(nlh, TIPC_NLA_MON_ACTIVATION_THRESHOLD, size); mnl_attr_nest_end(nlh, attrs); return msg_doit(nlh, NULL, NULL); }
static void nftnl_expr_lookup_build(struct nlmsghdr *nlh, struct nftnl_expr *e) { struct nftnl_expr_lookup *lookup = nftnl_expr_data(e); if (e->flags & (1 << NFTNL_EXPR_LOOKUP_SREG)) mnl_attr_put_u32(nlh, NFTA_LOOKUP_SREG, htonl(lookup->sreg)); if (e->flags & (1 << NFTNL_EXPR_LOOKUP_DREG)) mnl_attr_put_u32(nlh, NFTA_LOOKUP_DREG, htonl(lookup->dreg)); if (e->flags & (1 << NFTNL_EXPR_LOOKUP_SET)) mnl_attr_put_strz(nlh, NFTA_LOOKUP_SET, lookup->set_name); if (e->flags & (1 << NFTNL_EXPR_LOOKUP_SET_ID)) { mnl_attr_put_u32(nlh, NFTA_LOOKUP_SET_ID, htonl(lookup->set_id)); } }
static int cmd_node_set_netid(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, void *data) { int netid; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlattr *nest; if (help_flag) { (cmd->help)(cmdl); return -EINVAL; } if (!(nlh = msg_init(buf, TIPC_NL_NET_SET))) { fprintf(stderr, "error, message initialisation failed\n"); return -1; } if (cmdl->argc != cmdl->optind + 1) { fprintf(stderr, "Usage: %s node set netid NETID\n", cmdl->argv[0]); return -EINVAL; } netid = atoi(shift_cmdl(cmdl)); nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET); mnl_attr_put_u32(nlh, TIPC_NLA_NET_ID, netid); mnl_attr_nest_end(nlh, nest); return msg_doit(nlh, NULL, NULL); }
static int cmd_node_set_addr(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, void *data) { char *str; uint32_t addr; struct nlattr *nest; char buf[MNL_SOCKET_BUFFER_SIZE]; if (cmdl->argc != cmdl->optind + 1) { fprintf(stderr, "Usage: %s node set address ADDRESS\n", cmdl->argv[0]); return -EINVAL; } str = shift_cmdl(cmdl); addr = str2addr(str); if (!addr) return -1; if (!(nlh = msg_init(buf, TIPC_NL_NET_SET))) { fprintf(stderr, "error, message initialisation failed\n"); return -1; } nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET); mnl_attr_put_u32(nlh, TIPC_NLA_NET_ADDR, addr); mnl_attr_nest_end(nlh, nest); return msg_doit(nlh, NULL, NULL); }
/* Add/delete ip rule */ static int32_t multi_link_modify_rule(uint32_t msg_type, uint32_t flags, uint32_t table_id, struct multi_link_info *li){ uint8_t buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct rtmsg *rt; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = msg_type; nlh->nlmsg_flags = NLM_F_REQUEST | flags; nlh->nlmsg_seq = 0; rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg)); rt->rtm_family = AF_INET; rt->rtm_dst_len = 0; rt->rtm_table = table_id; //The table to perform the lookup in rt->rtm_protocol = RTPROT_BOOT; rt->rtm_scope = RT_SCOPE_UNIVERSE; rt->rtm_type = RTN_UNICAST; //Need the length of the src address that will be provided later on rt->rtm_src_len = 32; mnl_attr_put_u32(nlh, FRA_SRC, li->cfg.address.s_addr); if(mnl_socket_sendto(multi_link_nl_set, nlh, nlh->nlmsg_len) < 0){ MULTI_DEBUG_PRINT(stderr,"Could not send gateway to kernel " "(can be ignored if caused by an interface that went down, " "iface idx %u)\n", li->ifi_idx); return -1; } return 0; }
int mnlg_socket_group_add(struct mnlg_socket *nlg, const char *group_name) { struct nlmsghdr *nlh; struct group_info group_info; int err; nlh = __mnlg_msg_prepare(nlg, CTRL_CMD_GETFAMILY, NLM_F_REQUEST | NLM_F_ACK, GENL_ID_CTRL, 1); mnl_attr_put_u32(nlh, CTRL_ATTR_FAMILY_ID, nlg->id); err = mnlg_socket_send(nlg, nlh); if (err < 0) return err; group_info.found = false; group_info.name = group_name; err = mnlg_socket_recv_run(nlg, get_group_id_cb, &group_info); if (err < 0) return err; if (!group_info.found) { errno = ENOENT; return -1; } err = mnl_socket_setsockopt(nlg->nl, NETLINK_ADD_MEMBERSHIP, &group_info.id, sizeof(group_info.id)); if (err < 0) return err; return 0; }
static int cmd_link_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, void *data) { int val; int prop; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlattr *props; struct nlattr *attrs; struct opt *opt; struct opt opts[] = { { "link", OPT_KEYVAL, NULL }, { NULL } }; if (strcmp(cmd->cmd, PRIORITY_STR) == 0) prop = TIPC_NLA_PROP_PRIO; else if ((strcmp(cmd->cmd, TOLERANCE_STR) == 0)) prop = TIPC_NLA_PROP_TOL; else if ((strcmp(cmd->cmd, WINDOW_STR) == 0)) prop = TIPC_NLA_PROP_WIN; else return -EINVAL; if (help_flag) { (cmd->help)(cmdl); return -EINVAL; } if (cmdl->optind >= cmdl->argc) { fprintf(stderr, "error, missing value\n"); return -EINVAL; } val = atoi(shift_cmdl(cmdl)); if (parse_opts(opts, cmdl) < 0) return -EINVAL; nlh = msg_init(buf, TIPC_NL_LINK_SET); if (!nlh) { fprintf(stderr, "error, message initialisation failed\n"); return -1; } attrs = mnl_attr_nest_start(nlh, TIPC_NLA_LINK); opt = get_opt(opts, "link"); if (!opt) { fprintf(stderr, "error, missing link\n"); return -EINVAL; } mnl_attr_put_strz(nlh, TIPC_NLA_LINK_NAME, opt->val); props = mnl_attr_nest_start(nlh, TIPC_NLA_LINK_PROP); mnl_attr_put_u32(nlh, prop, val); mnl_attr_nest_end(nlh, props); mnl_attr_nest_end(nlh, attrs); return msg_doit(nlh, link_get_cb, &prop); }
int main(int argc, char *argv[]) { struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct genlmsghdr *genl; int ret; unsigned int seq, portid; if (argc != 2) { printf("%s [family name]\n", argv[0]); exit(EXIT_FAILURE); } nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = GENL_ID_CTRL; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; nlh->nlmsg_seq = seq = time(NULL); genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr)); genl->cmd = CTRL_CMD_GETFAMILY; genl->version = 1; mnl_attr_put_u32(nlh, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL); mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, argv[1]); nl = mnl_socket_open(NETLINK_GENERIC); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); while (ret > 0) { ret = mnl_cb_run(buf, ret, seq, portid, data_cb, NULL); if (ret <= 0) break; ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret == -1) { perror("error"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
static void nft_rule_expr_log_build(struct nlmsghdr *nlh, struct nft_rule_expr *e) { struct nft_expr_log *log = nft_expr_data(e); if (e->flags & (1 << NFT_EXPR_LOG_PREFIX)) mnl_attr_put_strz(nlh, NFTA_LOG_PREFIX, log->prefix); if (e->flags & (1 << NFT_EXPR_LOG_GROUP)) mnl_attr_put_u16(nlh, NFTA_LOG_GROUP, htons(log->group)); if (e->flags & (1 << NFT_EXPR_LOG_SNAPLEN)) mnl_attr_put_u32(nlh, NFTA_LOG_SNAPLEN, htonl(log->snaplen)); if (e->flags & (1 << NFT_EXPR_LOG_QTHRESHOLD)) mnl_attr_put_u16(nlh, NFTA_LOG_QTHRESHOLD, htons(log->qthreshold)); if (e->flags & (1 << NFT_EXPR_LOG_LEVEL)) mnl_attr_put_u32(nlh, NFTA_LOG_LEVEL, htonl(log->level)); if (e->flags & (1 << NFT_EXPR_LOG_FLAGS)) mnl_attr_put_u32(nlh, NFTA_LOG_FLAGS, htonl(log->flags)); }
/* Add/delete gateway */ static int32_t multi_link_modify_gateway(uint32_t msg_type, uint32_t flags, uint32_t table_id, struct multi_link_info *li, uint32_t metric){ uint8_t buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct rtmsg *rt; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = msg_type; nlh->nlmsg_flags = NLM_F_REQUEST | flags; nlh->nlmsg_seq = 0; rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg)); rt->rtm_family = AF_INET; //There is no destination (the destination is global, i.e. netmask 0) rt->rtm_dst_len = 0; rt->rtm_table = table_id; rt->rtm_protocol = RTPROT_UNSPEC; /* This is all copied from iproute */ if(msg_type != RTM_DELROUTE){ rt->rtm_scope = RT_SCOPE_UNIVERSE; rt->rtm_type = RTN_UNICAST; rt->rtm_protocol = RTPROT_BOOT; } else rt->rtm_scope = RT_SCOPE_NOWHERE; if(li->cfg.gateway.s_addr > 0) mnl_attr_put_u32(nlh, RTA_GATEWAY, li->cfg.gateway.s_addr); mnl_attr_put_u32(nlh, RTA_PREFSRC, li->cfg.address.s_addr); mnl_attr_put_u32(nlh, RTA_OIF, li->ifi_idx); if(metric) mnl_attr_put_u32(nlh, RTA_PRIORITY, metric); if(mnl_socket_sendto(multi_link_nl_set, nlh, nlh->nlmsg_len) < 0){ MULTI_DEBUG_PRINT(stderr,"Could not send gateway to kernel " "(can be ignored if caused by an interface that went down, " "iface idx %u)\n", li->ifi_idx); return -1; } return 0; }
static void nftnl_expr_target_build(struct nlmsghdr *nlh, const struct nftnl_expr *e) { struct nftnl_expr_target *tg = nftnl_expr_data(e); if (e->flags & (1 << NFTNL_EXPR_TG_NAME)) mnl_attr_put_strz(nlh, NFTA_TARGET_NAME, tg->name); if (e->flags & (1 << NFTNL_EXPR_TG_REV)) mnl_attr_put_u32(nlh, NFTA_TARGET_REV, htonl(tg->rev)); if (e->flags & (1 << NFTNL_EXPR_TG_INFO)) mnl_attr_put(nlh, NFTA_TARGET_INFO, tg->data_len, tg->data); }
static void nft_rule_expr_match_build(struct nlmsghdr *nlh, struct nft_rule_expr *e) { struct nft_expr_match *mt = nft_expr_data(e); if (e->flags & (1 << NFT_EXPR_MT_NAME)) mnl_attr_put_strz(nlh, NFTA_MATCH_NAME, mt->name); if (e->flags & (1 << NFT_EXPR_MT_REV)) mnl_attr_put_u32(nlh, NFTA_MATCH_REV, htonl(mt->rev)); if (e->flags & (1 << NFT_EXPR_MT_INFO)) mnl_attr_put(nlh, NFTA_MATCH_INFO, mt->data_len, mt->data); }
/* Adds or deletes the IP of an interface. This function is never called for PPP * interfaces, thus, there are no special cases. */ static int32_t multi_link_modify_ip(uint32_t msg_type, uint32_t flags, struct multi_link_info *li){ uint8_t buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct ifaddrmsg *ifa; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = msg_type; nlh->nlmsg_flags = NLM_F_REQUEST | flags; nlh->nlmsg_seq = 0; ifa = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifaddrmsg)); /* Fill in info related to address */ ifa->ifa_family = AF_INET; //Currently only IPv4 //To avoid this rule that is generated automatically, set bitlen to 32 ifa->ifa_prefixlen = 32 - (ffs(ntohl(li->cfg.netmask.s_addr)) - 1); //Only reason for changing this is if loopback ifa->ifa_scope = RT_SCOPE_UNIVERSE; ifa->ifa_index = li->ifi_idx; mnl_attr_put_u32(nlh, IFA_LOCAL, li->cfg.address.s_addr); mnl_attr_put_u32(nlh, IFA_ADDRESS, li->cfg.address.s_addr); if(li->cfg.broadcast.s_addr) mnl_attr_put_u32(nlh, IFA_BROADCAST, li->cfg.broadcast.s_addr); if(mnl_socket_sendto(multi_link_nl_set, nlh, nlh->nlmsg_len) < 0){ MULTI_DEBUG_PRINT(stderr,"Could not send IP to kernel (can be ignored " "if caused by an interface that went down, iface idx %u)\n", li->ifi_idx); return -1; } return 0; }
static void put_msg(char *buf, uint16_t i, int seq) { struct nlmsghdr *nlh; struct nfgenmsg *nfh; struct nlattr *nest1, *nest2; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW; nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK; nlh->nlmsg_seq = seq; nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg)); nfh->nfgen_family = AF_INET; nfh->version = NFNETLINK_V0; nfh->res_id = 0; nest1 = mnl_attr_nest_start(nlh, CTA_TUPLE_ORIG); nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_IP); mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, inet_addr("1.1.1.1")); mnl_attr_put_u32(nlh, CTA_IP_V4_DST, inet_addr("2.2.2.2")); mnl_attr_nest_end(nlh, nest2); nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO); mnl_attr_put_u8(nlh, CTA_PROTO_NUM, IPPROTO_TCP); mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(i)); mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(1025)); mnl_attr_nest_end(nlh, nest2); mnl_attr_nest_end(nlh, nest1); nest1 = mnl_attr_nest_start(nlh, CTA_TUPLE_REPLY); nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_IP); mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, inet_addr("2.2.2.2")); mnl_attr_put_u32(nlh, CTA_IP_V4_DST, inet_addr("1.1.1.1")); mnl_attr_nest_end(nlh, nest2); nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO); mnl_attr_put_u8(nlh, CTA_PROTO_NUM, IPPROTO_TCP); mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(1025)); mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(i)); mnl_attr_nest_end(nlh, nest2); mnl_attr_nest_end(nlh, nest1); nest1 = mnl_attr_nest_start(nlh, CTA_PROTOINFO); nest2 = mnl_attr_nest_start(nlh, CTA_PROTOINFO_TCP); mnl_attr_put_u8(nlh, CTA_PROTOINFO_TCP_STATE, TCP_CONNTRACK_SYN_SENT); mnl_attr_nest_end(nlh, nest2); mnl_attr_nest_end(nlh, nest1); mnl_attr_put_u32(nlh, CTA_STATUS, htonl(IPS_CONFIRMED)); mnl_attr_put_u32(nlh, CTA_TIMEOUT, htonl(1000)); }
static struct nlmsghdr * genl_nlmsg_build_lookup(char *buf, const char *subsys_name) { struct nlmsghdr *nlh; struct genlmsghdr *genl; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = GENL_ID_CTRL; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; nlh->nlmsg_seq = time(NULL); genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr)); genl->cmd = CTRL_CMD_GETFAMILY; genl->version = 1; mnl_attr_put_u32(nlh, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL); mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, subsys_name); return nlh; }
static int link_mon_peer_list(uint32_t mon_ref) { struct nlmsghdr *nlh; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlattr *nest; int err = 0; nlh = msg_init(buf, TIPC_NL_MON_PEER_GET); if (!nlh) { fprintf(stderr, "error, message initialisation failed\n"); return -1; } nest = mnl_attr_nest_start(nlh, TIPC_NLA_MON); mnl_attr_put_u32(nlh, TIPC_NLA_MON_REF, mon_ref); mnl_attr_nest_end(nlh, nest); err = msg_dumpit(nlh, link_mon_peer_list_cb, NULL); return err; }
int main(void) { char buf[getpagesize()]; struct nlmsghdr *nlh; struct mnl_socket *nl; int ret; unsigned int seq, portid; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = NLEX_MSG_UPD; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; nlh->nlmsg_seq = seq = time(NULL); nlh->nlmsg_pid = getpid(); mnl_attr_put_u32(nlh, NLE_MYVAR, 31337); nl = mnl_socket_open(NETLINK_EXAMPLE); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } portid = mnl_socket_get_portid(nl); if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_sendto"); exit(EXIT_FAILURE); } ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL); if (ret == -1) { perror("mnl_cb_callback"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
static void nft_rule_expr_nat_build(struct nlmsghdr *nlh, struct nft_rule_expr *e) { struct nft_expr_nat *nat = nft_expr_data(e); if (e->flags & (1 << NFT_EXPR_NAT_TYPE)) mnl_attr_put_u32(nlh, NFTA_NAT_TYPE, htonl(nat->type)); if (e->flags & (1 << NFT_EXPR_NAT_FAMILY)) mnl_attr_put_u32(nlh, NFTA_NAT_FAMILY, htonl(nat->family)); if (e->flags & (1 << NFT_EXPR_NAT_REG_ADDR_MIN)) mnl_attr_put_u32(nlh, NFTA_NAT_REG_ADDR_MIN, htonl(nat->sreg_addr_min)); if (e->flags & (1 << NFT_EXPR_NAT_REG_ADDR_MAX)) mnl_attr_put_u32(nlh, NFTA_NAT_REG_ADDR_MAX, htonl(nat->sreg_addr_max)); if (e->flags & (1 << NFT_EXPR_NAT_REG_PROTO_MIN)) mnl_attr_put_u32(nlh, NFTA_NAT_REG_PROTO_MIN, htonl(nat->sreg_proto_min)); if (e->flags & (1 << NFT_EXPR_NAT_REG_PROTO_MAX)) mnl_attr_put_u32(nlh, NFTA_NAT_REG_PROTO_MAX, htonl(nat->sreg_proto_max)); if (e->flags & (1 << NFT_EXPR_NAT_FLAGS)) mnl_attr_put_u32(nlh, NFTA_NAT_FLAGS, htonl(nat->flags)); }
int main(int argc, char *argv[]) { if (argc <= 3) { printf("Usage: %s iface destination cidr [gateway]\n", argv[0]); printf("Example: %s eth0 10.0.1.12 32 10.0.1.11\n", argv[0]); exit(EXIT_FAILURE); } int iface; iface = if_nametoindex(argv[1]); if (iface == 0) { printf("Bad interface name\n"); exit(EXIT_FAILURE); } in_addr_t dst; if (!inet_pton(AF_INET, argv[2], &dst)) { printf("Bad destination\n"); exit(EXIT_FAILURE); } uint32_t mask; if (sscanf(argv[3], "%u", &mask) == 0) { printf("Bad CIDR\n"); exit(EXIT_FAILURE); } in_addr_t gw; if (argc >= 5 && !inet_pton(AF_INET, argv[4], &gw)) { printf("Bad gateway\n"); exit(EXIT_FAILURE); } struct mnl_socket *nl; char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct rtmsg *rtm; nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = RTM_NEWROUTE; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; nlh->nlmsg_seq = time(NULL); rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg)); rtm->rtm_family = AF_INET; rtm->rtm_dst_len = mask; rtm->rtm_src_len = 0; rtm->rtm_tos = 0; rtm->rtm_protocol = RTPROT_BOOT; rtm->rtm_table = RT_TABLE_MAIN; rtm->rtm_type = RTN_UNICAST; /* is there any gateway? */ rtm->rtm_scope = (argc == 4) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE; rtm->rtm_flags = 0; mnl_attr_put_u32(nlh, RTA_DST, dst); mnl_attr_put_u32(nlh, RTA_OIF, iface); if (argc >= 5) mnl_attr_put_u32(nlh, RTA_GATEWAY, gw); nl = mnl_socket_open(NETLINK_ROUTE); if (nl == NULL) { perror("mnl_socket_open"); exit(EXIT_FAILURE); } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { perror("mnl_socket_bind"); exit(EXIT_FAILURE); } if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { perror("mnl_socket_send"); exit(EXIT_FAILURE); } mnl_socket_close(nl); return 0; }
int main(int argc, char *argv[]){ struct mnl_socket *nl_sock = NULL; struct nlmsghdr *nlh = NULL; struct nlmsgerr *nlerr = NULL; struct nlattr *linkinfo = NULL, *tunnelinfo = NULL; struct ifinfomsg *ifinfo = NULL; uint8_t buf[MNL_SOCKET_BUFFER_SIZE]; size_t numbytes = 0; struct in_addr addr; memset(buf, 0, sizeof(buf)); if((nl_sock = mnl_socket_open(NETLINK_ROUTE)) == NULL){ perror("mnl_socket_open: "); exit(EXIT_FAILURE); } //Add and configure header nlh = mnl_nlmsg_put_header(buf); //Create only if interface does not exists from before (EXCL) nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK; nlh->nlmsg_type = RTM_NEWLINK; //see rtnl_newlink in net/core/rtnetlink.c for observing how this function //works ifinfo = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifinfomsg)); ifinfo->ifi_family = AF_UNSPEC; //Add a name and mtu, for testing mnl_attr_put_str(nlh, IFLA_IFNAME, "kre2"); mnl_attr_put_u32(nlh, IFLA_MTU, 1234); //Type is required, set to IPIP linkinfo = mnl_attr_nest_start(nlh, IFLA_LINKINFO); mnl_attr_put_str(nlh, IFLA_INFO_KIND, "ipip"); //Add information about the tunnel tunnelinfo = mnl_attr_nest_start(nlh, IFLA_INFO_DATA); inet_pton(AF_INET, "192.168.203.19", &addr); mnl_attr_put_u32(nlh, IFLA_IPTUN_LOCAL, addr.s_addr); inet_pton(AF_INET, "10.0.0.2", &addr); mnl_attr_put_u32(nlh, IFLA_IPTUN_REMOTE, addr.s_addr); mnl_attr_nest_end(nlh, tunnelinfo); mnl_attr_nest_end(nlh, linkinfo); numbytes = mnl_socket_sendto(nl_sock, nlh, nlh->nlmsg_len); numbytes = mnl_socket_recvfrom(nl_sock, buf, sizeof(buf)); nlh = (struct nlmsghdr*) buf; if(nlh->nlmsg_type == NLMSG_ERROR){ nlerr = mnl_nlmsg_get_payload(nlh); //error==0 for ack if(nlerr->error) printf("Error: %s\n", strerror(-nlerr->error)); } else { printf("Link added\n"); } return EXIT_FAILURE; }
void nfq_nlmsg_verdict_put_mark(struct nlmsghdr *nlh, uint32_t mark) { mnl_attr_put_u32(nlh, NFQA_MARK, htonl(mark)); }
void nfq_nlmsg_cfg_put_qmaxlen(struct nlmsghdr *nlh, uint32_t queue_maxlen) { mnl_attr_put_u32(nlh, NFQA_CFG_QUEUE_MAXLEN, htonl(queue_maxlen)); }