144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 21155370f520cb64657e25153255cf7dc1424317fThomas Graf * lib/socket.c Netlink Socket 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 98a3efffa5b3fde252675239914118664d36a2c24Thomas Graf * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 136782b6f709d03877a5661a4c8d8f8bd1b461f43fThomas Graf * @ingroup core 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @defgroup socket Socket 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-local.h> 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h> 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/utils.h> 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/handlers.h> 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/msg.h> 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/attr.h> 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf 25680c54fd4616649763a50b122df6cff53b9e62bdThomas Grafstatic int default_cb = NL_CB_DEFAULT; 26680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf 27680c54fd4616649763a50b122df6cff53b9e62bdThomas Grafstatic void __init init_default_cb(void) 28680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf{ 29680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf char *nlcb; 30680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf 31680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf if ((nlcb = getenv("NLCB"))) { 32680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf if (!strcasecmp(nlcb, "default")) 33680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf default_cb = NL_CB_DEFAULT; 34680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf else if (!strcasecmp(nlcb, "verbose")) 35680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf default_cb = NL_CB_VERBOSE; 36680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf else if (!strcasecmp(nlcb, "debug")) 37680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf default_cb = NL_CB_DEBUG; 38680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf else { 39680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf fprintf(stderr, "Unknown value for NLCB, valid values: " 40680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf "{default | verbose | debug}\n"); 41680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf } 42680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf } 43680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf} 44680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf 4544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic uint32_t used_ports_map[32]; 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf 4744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic uint32_t generate_local_port(void) 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, n; 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t pid = getpid() & 0x3FFFFF; 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i < 32; i++) { 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (used_ports_map[i] == 0xFFFFFFFF) 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf continue; 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf for (n = 0; n < 32; n++) { 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (1UL & (used_ports_map[i] >> n)) 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf continue; 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf used_ports_map[i] |= (1UL << n); 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf n += (i * 32); 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf /* PID_MAX_LIMIT is currently at 2^22, leaving 10 bit 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf * to, i.e. 1024 unique ports per application. */ 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf return pid + (n << 22); 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf /* Out of sockets in our own PID namespace, what to do? FIXME */ 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf return UINT_MAX; 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf 7444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void release_local_port(uint32_t port) 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 7691c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf int nr; 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf 7891c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf if (port == UINT_MAX) 7991c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf return; 8091c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf 8191c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf nr = port >> 22; 82ef8ba32e0ca7ac7bbbaf87f6fd7b197af18aed25Inaky Perez-Gonzalez used_ports_map[nr / 32] &= ~(1 << nr % 32); 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf 901155370f520cb64657e25153255cf7dc1424317fThomas Grafstatic struct nl_sock *__alloc_socket(struct nl_cb *cb) 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 921155370f520cb64657e25153255cf7dc1424317fThomas Graf struct nl_sock *sk; 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf 941155370f520cb64657e25153255cf7dc1424317fThomas Graf sk = calloc(1, sizeof(*sk)); 951155370f520cb64657e25153255cf7dc1424317fThomas Graf if (!sk) 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf 981155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_fd = -1; 991155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_cb = cb; 1001155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_local.nl_family = AF_NETLINK; 1011155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_peer.nl_family = AF_NETLINK; 1021155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_seq_expect = sk->s_seq_next = time(0); 1031155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_local.nl_pid = generate_local_port(); 1041155370f520cb64657e25153255cf7dc1424317fThomas Graf if (sk->s_local.nl_pid == UINT_MAX) { 1051155370f520cb64657e25153255cf7dc1424317fThomas Graf nl_socket_free(sk); 10691c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf return NULL; 10791c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf } 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf 1091155370f520cb64657e25153255cf7dc1424317fThomas Graf return sk; 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 1131155370f520cb64657e25153255cf7dc1424317fThomas Graf * Allocate new netlink socket 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 1151155370f520cb64657e25153255cf7dc1424317fThomas Graf * @return Newly allocated netlink socket or NULL. 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1171155370f520cb64657e25153255cf7dc1424317fThomas Grafstruct nl_sock *nl_socket_alloc(void) 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cb *cb; 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf 121680c54fd4616649763a50b122df6cff53b9e62bdThomas Graf cb = nl_cb_alloc(default_cb); 1228a3efffa5b3fde252675239914118664d36a2c24Thomas Graf if (!cb) 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 12444d362409d5469aed47d19e7908d19bd194493aThomas Graf 1251155370f520cb64657e25153255cf7dc1424317fThomas Graf return __alloc_socket(cb); 12644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 12744d362409d5469aed47d19e7908d19bd194493aThomas Graf 12844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 1291155370f520cb64657e25153255cf7dc1424317fThomas Graf * Allocate new socket with custom callbacks 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cb Callback handler 13144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf * The reference to the callback handler is taken into account 1331155370f520cb64657e25153255cf7dc1424317fThomas Graf * automatically, it is released again upon calling nl_socket_free(). 13444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf *@return Newly allocted socket handle or NULL. 13644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1371155370f520cb64657e25153255cf7dc1424317fThomas Grafstruct nl_sock *nl_socket_alloc_cb(struct nl_cb *cb) 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 13944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (cb == NULL) 14044d362409d5469aed47d19e7908d19bd194493aThomas Graf BUG(); 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf 1421155370f520cb64657e25153255cf7dc1424317fThomas Graf return __alloc_socket(nl_cb_get(cb)); 14344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 14444d362409d5469aed47d19e7908d19bd194493aThomas Graf 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 1461155370f520cb64657e25153255cf7dc1424317fThomas Graf * Free a netlink socket. 1471155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1491155370f520cb64657e25153255cf7dc1424317fThomas Grafvoid nl_socket_free(struct nl_sock *sk) 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1511155370f520cb64657e25153255cf7dc1424317fThomas Graf if (!sk) 15244d362409d5469aed47d19e7908d19bd194493aThomas Graf return; 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf 1541155370f520cb64657e25153255cf7dc1424317fThomas Graf if (sk->s_fd >= 0) 1551155370f520cb64657e25153255cf7dc1424317fThomas Graf close(sk->s_fd); 15691c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf 1571155370f520cb64657e25153255cf7dc1424317fThomas Graf if (!(sk->s_flags & NL_OWN_PORT)) 1581155370f520cb64657e25153255cf7dc1424317fThomas Graf release_local_port(sk->s_local.nl_pid); 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf 1601155370f520cb64657e25153255cf7dc1424317fThomas Graf nl_cb_put(sk->s_cb); 1611155370f520cb64657e25153255cf7dc1424317fThomas Graf free(sk); 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf 16444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Sequence Numbers 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 16944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf 17144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int noop_seq_check(struct nl_msg *msg, void *arg) 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf return NL_OK; 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Disable sequence number checking. 1791155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 18044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 1811155370f520cb64657e25153255cf7dc1424317fThomas Graf * Disables checking of sequence numbers on the netlink socket This is 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf * required to allow messages to be processed which were not requested by 18344d362409d5469aed47d19e7908d19bd194493aThomas Graf * a preceding request message, e.g. netlink events. 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note This function modifies the NL_CB_SEQ_CHECK configuration in 18644d362409d5469aed47d19e7908d19bd194493aThomas Graf * the callback handle associated with the socket. 18744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 188724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Grafvoid nl_socket_disable_seq_check(struct nl_sock *sk) 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1901155370f520cb64657e25153255cf7dc1424317fThomas Graf nl_cb_set(sk->s_cb, NL_CB_SEQ_CHECK, 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf NL_CB_CUSTOM, noop_seq_check, NULL); 19244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 19344d362409d5469aed47d19e7908d19bd194493aThomas Graf 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 19544d362409d5469aed47d19e7908d19bd194493aThomas Graf * Use next sequence number 1961155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 19844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Uses the next available sequence number and increases the counter 19944d362409d5469aed47d19e7908d19bd194493aThomas Graf * by one for subsequent calls. 20044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 20144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return Unique serial sequence number 20244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 2031155370f520cb64657e25153255cf7dc1424317fThomas Grafunsigned int nl_socket_use_seq(struct nl_sock *sk) 20444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 2051155370f520cb64657e25153255cf7dc1424317fThomas Graf return sk->s_seq_next++; 20644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 20744d362409d5469aed47d19e7908d19bd194493aThomas Graf 2082bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf/** 2092bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * Disable automatic request for ACK 2102bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * @arg sk Netlink socket. 2112bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * 2122bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * The default behaviour of a socket is to request an ACK for 2132bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * each message sent to allow for the caller to synchronize to 2142bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * the completion of the netlink operation. This function 2152bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * disables this behaviour and will result in requests being 2162bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * sent which will not have the NLM_F_ACK flag set automatically. 2172bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * However, it is still possible for the caller to set the 2182bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * NLM_F_ACK flag explicitely. 2192bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf */ 2202bdee95a765457fe4206b89d51974ae56e75c588Thomas Grafvoid nl_socket_disable_auto_ack(struct nl_sock *sk) 2212bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf{ 2222bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf sk->s_flags |= NL_NO_AUTO_ACK; 2232bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf} 2242bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf 2252bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf/** 2262bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * Enable automatic request for ACK (default) 2272bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * @arg sk Netlink socket. 2282bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf * @see nl_socket_disable_auto_ack 2292bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf */ 2302bdee95a765457fe4206b89d51974ae56e75c588Thomas Grafvoid nl_socket_enable_auto_ack(struct nl_sock *sk) 2312bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf{ 2322bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf sk->s_flags &= ~NL_NO_AUTO_ACK; 2332bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf} 2342bdee95a765457fe4206b89d51974ae56e75c588Thomas Graf 23544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 23844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Source Idenficiation 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 24044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 24144d362409d5469aed47d19e7908d19bd194493aThomas Graf 2421155370f520cb64657e25153255cf7dc1424317fThomas Grafuint32_t nl_socket_get_local_port(struct nl_sock *sk) 24344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 2441155370f520cb64657e25153255cf7dc1424317fThomas Graf return sk->s_local.nl_pid; 24544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 24644d362409d5469aed47d19e7908d19bd194493aThomas Graf 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Set local port of socket 2491155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 25044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg port Local port identifier 25144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 25244d362409d5469aed47d19e7908d19bd194493aThomas Graf * Assigns a local port identifier to the socket. If port is 0 25344d362409d5469aed47d19e7908d19bd194493aThomas Graf * a unique port identifier will be generated automatically. 25444d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 2551155370f520cb64657e25153255cf7dc1424317fThomas Grafvoid nl_socket_set_local_port(struct nl_sock *sk, uint32_t port) 25644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 25744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (port == 0) { 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf port = generate_local_port(); 2591155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_flags &= ~NL_OWN_PORT; 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf } else { 2611155370f520cb64657e25153255cf7dc1424317fThomas Graf if (!(sk->s_flags & NL_OWN_PORT)) 2621155370f520cb64657e25153255cf7dc1424317fThomas Graf release_local_port(sk->s_local.nl_pid); 2631155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_flags |= NL_OWN_PORT; 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 26544d362409d5469aed47d19e7908d19bd194493aThomas Graf 2661155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_local.nl_pid = port; 26744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 26844d362409d5469aed47d19e7908d19bd194493aThomas Graf 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 27044d362409d5469aed47d19e7908d19bd194493aThomas Graf 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Group Subscriptions 27344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 27772aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger * Join groups 2781155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg group Group identifier 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 28172aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger * Joins the specified groups using the modern socket option which 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf * is available since kernel version 2.6.14. It allows joining an 28372aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger * almost arbitary number of groups without limitation. The list 28472aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger * of groups has to be terminated by 0 (%NFNLGRP_NONE). 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf * Make sure to use the correct group definitions as the older 28744d362409d5469aed47d19e7908d19bd194493aThomas Graf * bitmask definitions for nl_join_groups() are likely to still 28844d362409d5469aed47d19e7908d19bd194493aThomas Graf * be present for backward compatibility reasons. 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf * 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on sucess or a negative error code. 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 29272aa861c48b6876e94d07470025155a6924a6983Holger Eitzenbergerint nl_socket_add_memberships(struct nl_sock *sk, int group, ...) 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 29572aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger va_list ap; 29644d362409d5469aed47d19e7908d19bd194493aThomas Graf 2971155370f520cb64657e25153255cf7dc1424317fThomas Graf if (sk->s_fd == -1) 2988a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_BAD_SOCK; 29991c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf 30072aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger va_start(ap, group); 30172aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger 30272aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger while (group != 0) { 30372aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger if (group < 0) 30472aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger return -NLE_INVAL; 30572aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger 30672aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, 30772aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger &group, sizeof(group)); 30872aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger if (err < 0) 30972aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger return -nl_syserr2nlerr(errno); 31072aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger 31172aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger group = va_arg(ap, int); 31272aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger } 31372aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger 31472aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger va_end(ap); 31544d362409d5469aed47d19e7908d19bd194493aThomas Graf 31644d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 31744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 31844d362409d5469aed47d19e7908d19bd194493aThomas Graf 319724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Grafint nl_socket_add_membership(struct nl_sock *sk, int group) 320724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Graf{ 321724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Graf return nl_socket_add_memberships(sk, group, 0); 322724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Graf} 323724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Graf 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 32572aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger * Leave groups 3261155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg group Group identifier 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 32972aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger * Leaves the specified groups using the modern socket option 33072aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger * which is available since kernel version 2.6.14. The list of groups 33172aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger * has to terminated by 0 (%NFNLGRP_NONE). 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @see nl_socket_add_membership 33444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on success or a negative error code. 33544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 33672aa861c48b6876e94d07470025155a6924a6983Holger Eitzenbergerint nl_socket_drop_memberships(struct nl_sock *sk, int group, ...) 33744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 33972aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger va_list ap; 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf 3411155370f520cb64657e25153255cf7dc1424317fThomas Graf if (sk->s_fd == -1) 3428a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_BAD_SOCK; 34391c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf 34472aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger va_start(ap, group); 34572aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger 34672aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger while (group != 0) { 34772aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger if (group < 0) 34872aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger return -NLE_INVAL; 34972aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger 35072aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, 35172aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger &group, sizeof(group)); 35272aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger if (err < 0) 35372aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger return -nl_syserr2nlerr(errno); 35472aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger 35572aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger group = va_arg(ap, int); 35672aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger } 35772aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger 35872aa861c48b6876e94d07470025155a6924a6983Holger Eitzenberger va_end(ap); 35944d362409d5469aed47d19e7908d19bd194493aThomas Graf 36044d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf 363724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Grafint nl_socket_drop_membership(struct nl_sock *sk, int group) 364724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Graf{ 365724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Graf return nl_socket_drop_memberships(sk, group, 0); 366724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Graf} 367724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Graf 368724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Graf 36944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 37044d362409d5469aed47d19e7908d19bd194493aThomas Graf * Join multicast groups (deprecated) 3711155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 37244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg groups Bitmask of groups to join. 37344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 37444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This function defines the old way of joining multicast group which 37544d362409d5469aed47d19e7908d19bd194493aThomas Graf * has to be done prior to calling nl_connect(). It works on any kernel 37644d362409d5469aed47d19e7908d19bd194493aThomas Graf * version but is very limited as only 32 groups can be joined. 37744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 3781155370f520cb64657e25153255cf7dc1424317fThomas Grafvoid nl_join_groups(struct nl_sock *sk, int groups) 37944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 3801155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_local.nl_groups |= groups; 38144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 38244d362409d5469aed47d19e7908d19bd194493aThomas Graf 38344d362409d5469aed47d19e7908d19bd194493aThomas Graf 38444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 38544d362409d5469aed47d19e7908d19bd194493aThomas Graf 38644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 38744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Peer Identfication 38844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 38944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 39044d362409d5469aed47d19e7908d19bd194493aThomas Graf 3911155370f520cb64657e25153255cf7dc1424317fThomas Grafuint32_t nl_socket_get_peer_port(struct nl_sock *sk) 39244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 3931155370f520cb64657e25153255cf7dc1424317fThomas Graf return sk->s_peer.nl_pid; 39444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 39544d362409d5469aed47d19e7908d19bd194493aThomas Graf 3961155370f520cb64657e25153255cf7dc1424317fThomas Grafvoid nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port) 39744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 3981155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_peer.nl_pid = port; 39944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 40044d362409d5469aed47d19e7908d19bd194493aThomas Graf 40144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 40244d362409d5469aed47d19e7908d19bd194493aThomas Graf 40344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 40444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name File Descriptor 40544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 40644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 40744d362409d5469aed47d19e7908d19bd194493aThomas Graf 4081155370f520cb64657e25153255cf7dc1424317fThomas Grafint nl_socket_get_fd(struct nl_sock *sk) 40944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4101155370f520cb64657e25153255cf7dc1424317fThomas Graf return sk->s_fd; 41144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 41244d362409d5469aed47d19e7908d19bd194493aThomas Graf 41344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 4141155370f520cb64657e25153255cf7dc1424317fThomas Graf * Set file descriptor of socket to non-blocking state 4151155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 41644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 41744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on success or a negative error code. 41844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 4191155370f520cb64657e25153255cf7dc1424317fThomas Grafint nl_socket_set_nonblocking(struct nl_sock *sk) 42044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4211155370f520cb64657e25153255cf7dc1424317fThomas Graf if (sk->s_fd == -1) 4228a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_BAD_SOCK; 42391c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf 4241155370f520cb64657e25153255cf7dc1424317fThomas Graf if (fcntl(sk->s_fd, F_SETFL, O_NONBLOCK) < 0) 4258a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -nl_syserr2nlerr(errno); 42644d362409d5469aed47d19e7908d19bd194493aThomas Graf 42744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 42844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 42944d362409d5469aed47d19e7908d19bd194493aThomas Graf 43044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 43144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Enable use of MSG_PEEK when reading from socket 4321155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 43344d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 4341155370f520cb64657e25153255cf7dc1424317fThomas Grafvoid nl_socket_enable_msg_peek(struct nl_sock *sk) 43544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4361155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_flags |= NL_MSG_PEEK; 43744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 43844d362409d5469aed47d19e7908d19bd194493aThomas Graf 43944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 44044d362409d5469aed47d19e7908d19bd194493aThomas Graf * Disable use of MSG_PEEK when reading from socket 4411155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 44244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 4431155370f520cb64657e25153255cf7dc1424317fThomas Grafvoid nl_socket_disable_msg_peek(struct nl_sock *sk) 44444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4451155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_flags &= ~NL_MSG_PEEK; 44644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 44744d362409d5469aed47d19e7908d19bd194493aThomas Graf 44844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 44944d362409d5469aed47d19e7908d19bd194493aThomas Graf 45044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 45144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Callback Handler 45244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 45344d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 45444d362409d5469aed47d19e7908d19bd194493aThomas Graf 4551155370f520cb64657e25153255cf7dc1424317fThomas Grafstruct nl_cb *nl_socket_get_cb(struct nl_sock *sk) 45644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4571155370f520cb64657e25153255cf7dc1424317fThomas Graf return nl_cb_get(sk->s_cb); 45844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 45944d362409d5469aed47d19e7908d19bd194493aThomas Graf 4601155370f520cb64657e25153255cf7dc1424317fThomas Grafvoid nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb) 46144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4621155370f520cb64657e25153255cf7dc1424317fThomas Graf nl_cb_put(sk->s_cb); 4631155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_cb = nl_cb_get(cb); 46444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 46544d362409d5469aed47d19e7908d19bd194493aThomas Graf 46644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 46744d362409d5469aed47d19e7908d19bd194493aThomas Graf * Modify the callback handler associated to the socket 4681155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 46944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg type which type callback to set 47044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg kind kind of callback 47144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg func callback function 47244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg arg argument to be passwd to callback function 47344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 47444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @see nl_cb_set 47544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 4761155370f520cb64657e25153255cf7dc1424317fThomas Grafint nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, 47744d362409d5469aed47d19e7908d19bd194493aThomas Graf enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, 47844d362409d5469aed47d19e7908d19bd194493aThomas Graf void *arg) 47944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4801155370f520cb64657e25153255cf7dc1424317fThomas Graf return nl_cb_set(sk->s_cb, type, kind, func, arg); 48144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 48244d362409d5469aed47d19e7908d19bd194493aThomas Graf 48344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 48444d362409d5469aed47d19e7908d19bd194493aThomas Graf 48544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 48644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Utilities 48744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 48844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 48944d362409d5469aed47d19e7908d19bd194493aThomas Graf 49044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 4911155370f520cb64657e25153255cf7dc1424317fThomas Graf * Set socket buffer size of netlink socket. 4921155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 49344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg rxbuf New receive socket buffer size in bytes. 49444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg txbuf New transmit socket buffer size in bytes. 49544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 4961155370f520cb64657e25153255cf7dc1424317fThomas Graf * Sets the socket buffer size of a netlink socket to the specified 49744d362409d5469aed47d19e7908d19bd194493aThomas Graf * values \c rxbuf and \c txbuf. Providing a value of \c 0 assumes a 49844d362409d5469aed47d19e7908d19bd194493aThomas Graf * good default value. 49944d362409d5469aed47d19e7908d19bd194493aThomas Graf * 50044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note It is not required to call this function prior to nl_connect(). 50144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on sucess or a negative error code. 50244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 503724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Grafint nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf) 50444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 50544d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 50644d362409d5469aed47d19e7908d19bd194493aThomas Graf 50744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (rxbuf <= 0) 50844d362409d5469aed47d19e7908d19bd194493aThomas Graf rxbuf = 32768; 50944d362409d5469aed47d19e7908d19bd194493aThomas Graf 51044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (txbuf <= 0) 51144d362409d5469aed47d19e7908d19bd194493aThomas Graf txbuf = 32768; 51291c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf 5131155370f520cb64657e25153255cf7dc1424317fThomas Graf if (sk->s_fd == -1) 5148a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_BAD_SOCK; 51544d362409d5469aed47d19e7908d19bd194493aThomas Graf 5161155370f520cb64657e25153255cf7dc1424317fThomas Graf err = setsockopt(sk->s_fd, SOL_SOCKET, SO_SNDBUF, 51744d362409d5469aed47d19e7908d19bd194493aThomas Graf &txbuf, sizeof(txbuf)); 51844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 5198a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -nl_syserr2nlerr(errno); 52044d362409d5469aed47d19e7908d19bd194493aThomas Graf 5211155370f520cb64657e25153255cf7dc1424317fThomas Graf err = setsockopt(sk->s_fd, SOL_SOCKET, SO_RCVBUF, 52244d362409d5469aed47d19e7908d19bd194493aThomas Graf &rxbuf, sizeof(rxbuf)); 52344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 5248a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -nl_syserr2nlerr(errno); 52544d362409d5469aed47d19e7908d19bd194493aThomas Graf 5261155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_flags |= NL_SOCK_BUFSIZE_SET; 52744d362409d5469aed47d19e7908d19bd194493aThomas Graf 52844d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 52944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 53044d362409d5469aed47d19e7908d19bd194493aThomas Graf 53144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 5321155370f520cb64657e25153255cf7dc1424317fThomas Graf * Enable/disable credential passing on netlink socket. 5331155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 53444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg state New state (0 - disabled, 1 - enabled) 53544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 53644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on success or a negative error code 53744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 538724dfa6d70943e0d4e3c8e54bff43050828a64d0Thomas Grafint nl_socket_set_passcred(struct nl_sock *sk, int state) 53944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 54044d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 54144d362409d5469aed47d19e7908d19bd194493aThomas Graf 5421155370f520cb64657e25153255cf7dc1424317fThomas Graf if (sk->s_fd == -1) 5438a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_BAD_SOCK; 54491c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf 5451155370f520cb64657e25153255cf7dc1424317fThomas Graf err = setsockopt(sk->s_fd, SOL_SOCKET, SO_PASSCRED, 54644d362409d5469aed47d19e7908d19bd194493aThomas Graf &state, sizeof(state)); 54744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 5488a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -nl_syserr2nlerr(errno); 54944d362409d5469aed47d19e7908d19bd194493aThomas Graf 55044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (state) 5511155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_flags |= NL_SOCK_PASSCRED; 55244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 5531155370f520cb64657e25153255cf7dc1424317fThomas Graf sk->s_flags &= ~NL_SOCK_PASSCRED; 55444d362409d5469aed47d19e7908d19bd194493aThomas Graf 55544d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 55644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 55744d362409d5469aed47d19e7908d19bd194493aThomas Graf 55844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 55944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Enable/disable receival of additional packet information 5601155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 56144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg state New state (0 - disabled, 1 - enabled) 56244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 56344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on success or a negative error code 56444d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 5651155370f520cb64657e25153255cf7dc1424317fThomas Grafint nl_socket_recv_pktinfo(struct nl_sock *sk, int state) 56644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 56744d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 56844d362409d5469aed47d19e7908d19bd194493aThomas Graf 5691155370f520cb64657e25153255cf7dc1424317fThomas Graf if (sk->s_fd == -1) 5708a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_BAD_SOCK; 57191c330aae51cd6cd44ad730e10dc82724998c810Thomas Graf 5721155370f520cb64657e25153255cf7dc1424317fThomas Graf err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_PKTINFO, 57344d362409d5469aed47d19e7908d19bd194493aThomas Graf &state, sizeof(state)); 57444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 5758a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -nl_syserr2nlerr(errno); 57644d362409d5469aed47d19e7908d19bd194493aThomas Graf 57744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 57844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 57944d362409d5469aed47d19e7908d19bd194493aThomas Graf 58044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 58144d362409d5469aed47d19e7908d19bd194493aThomas Graf 58244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 583