static struct mnl_ring * mnl_socket_mmap(struct mnl_socket *nls, struct nl_mmap_req *req, int flags, int optname) { struct mnl_ring *nlr = alloc_ring(req); if (nlr == NULL) return NULL; if (mnl_socket_setsockopt(nls, optname, req, sizeof(*req)) == -1) goto fail; nlr->ring = mmap(NULL, ring_size(nlr), PROT_READ | PROT_WRITE, flags, mnl_socket_get_fd(nls), 0); if (nlr->ring == MAP_FAILED) goto fail; nlr->fd = mnl_socket_get_fd(nls); return nlr; fail: free(nlr); return NULL; }
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; }
/* method: setsockopt */ static int mnl_socket__setsockopt__meth(lua_State *L) { mnl_socket * this_idx1; int type_idx2; void * buf_idx3; socklen_t len_idx4; int rc_mnl_socket_setsockopt_idx1 = 0; this_idx1 = obj_type_mnl_socket_check(L,1); type_idx2 = luaL_checkinteger(L,2); buf_idx3 = lua_touserdata(L,3); len_idx4 = luaL_checkinteger(L,4); rc_mnl_socket_setsockopt_idx1 = mnl_socket_setsockopt(this_idx1, type_idx2, buf_idx3, len_idx4); lua_pushinteger(L, rc_mnl_socket_setsockopt_idx1); return 1; }
struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t version) { struct mnlg_socket *nlg; struct nlmsghdr *nlh; int one = 1; int err; nlg = malloc(sizeof(*nlg)); if (!nlg) return NULL; nlg->buf = malloc(MNL_SOCKET_BUFFER_SIZE); if (!nlg->buf) goto err_buf_alloc; nlg->nl = mnl_socket_open(NETLINK_GENERIC); if (!nlg->nl) goto err_mnl_socket_open; err = mnl_socket_setsockopt(nlg->nl, NETLINK_CAP_ACK, &one, sizeof(one)); if (err) goto err_mnl_set_ack; err = mnl_socket_setsockopt(nlg->nl, NETLINK_EXT_ACK, &one, sizeof(one)); if (err) goto err_mnl_set_ext_ack; err = mnl_socket_bind(nlg->nl, 0, MNL_SOCKET_AUTOPID); if (err < 0) goto err_mnl_socket_bind; nlg->portid = mnl_socket_get_portid(nlg->nl); nlh = __mnlg_msg_prepare(nlg, CTRL_CMD_GETFAMILY, NLM_F_REQUEST | NLM_F_ACK, GENL_ID_CTRL, 1); mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, family_name); err = mnlg_socket_send(nlg, nlh); if (err < 0) goto err_mnlg_socket_send; err = mnlg_socket_recv_run(nlg, get_family_id_cb, &nlg->id); if (err < 0) goto err_mnlg_socket_recv_run; nlg->version = version; return nlg; err_mnlg_socket_recv_run: err_mnlg_socket_send: err_mnl_socket_bind: err_mnl_set_ext_ack: err_mnl_set_ack: mnl_socket_close(nlg->nl); err_mnl_socket_open: free(nlg->buf); err_buf_alloc: free(nlg); return NULL; }