| 1 | /* |
| 2 | * netlink/socket.h Netlink Socket |
| 3 | * |
| 4 | * This library is free software; you can redistribute it and/or |
| 5 | * modify it under the terms of the GNU Lesser General Public |
| 6 | * License as published by the Free Software Foundation version 2.1 |
| 7 | * of the License. |
| 8 | * |
| 9 | * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> |
| 10 | */ |
| 11 | |
| 12 | #ifndef NETLINK_SOCKET_H_ |
| 13 | #define NETLINK_SOCKET_H_ |
| 14 | |
| 15 | #include <netlink/types.h> |
| 16 | #include <netlink/handlers.h> |
| 17 | |
| 18 | #ifdef __cplusplus |
| 19 | extern "C" { |
| 20 | #endif |
| 21 | |
| 22 | #define NL_SOCK_BUFSIZE_SET (1<<0) |
| 23 | #define NL_SOCK_PASSCRED (1<<1) |
| 24 | #define NL_OWN_PORT (1<<2) |
| 25 | #define NL_MSG_PEEK (1<<3) |
| 26 | #define NL_NO_AUTO_ACK (1<<4) |
| 27 | |
| 28 | struct nl_cb; |
| 29 | struct nl_sock |
| 30 | { |
| 31 | struct sockaddr_nl s_local; |
| 32 | struct sockaddr_nl s_peer; |
| 33 | int s_fd; |
| 34 | int s_proto; |
| 35 | unsigned int s_seq_next; |
| 36 | unsigned int s_seq_expect; |
| 37 | int s_flags; |
| 38 | struct nl_cb * s_cb; |
| 39 | }; |
| 40 | |
| 41 | |
| 42 | extern struct nl_sock * nl_socket_alloc(void); |
| 43 | extern struct nl_sock * nl_socket_alloc_cb(struct nl_cb *); |
| 44 | extern void nl_socket_free(struct nl_sock *); |
| 45 | |
| 46 | extern void nl_socket_set_local_port(struct nl_sock *, uint32_t); |
| 47 | |
| 48 | extern int nl_socket_add_memberships(struct nl_sock *, int, ...); |
| 49 | extern int nl_socket_drop_memberships(struct nl_sock *, int, ...); |
| 50 | |
| 51 | extern int nl_socket_set_buffer_size(struct nl_sock *, int, int); |
| 52 | extern int nl_socket_set_passcred(struct nl_sock *, int); |
| 53 | extern int nl_socket_recv_pktinfo(struct nl_sock *, int); |
| 54 | |
| 55 | extern void nl_socket_disable_seq_check(struct nl_sock *); |
| 56 | |
| 57 | extern int nl_socket_set_nonblocking(struct nl_sock *); |
| 58 | |
| 59 | /** |
| 60 | * Use next sequence number |
| 61 | * @arg sk Netlink socket. |
| 62 | * |
| 63 | * Uses the next available sequence number and increases the counter |
| 64 | * by one for subsequent calls. |
| 65 | * |
| 66 | * @return Unique serial sequence number |
| 67 | */ |
| 68 | static inline unsigned int nl_socket_use_seq(struct nl_sock *sk) |
| 69 | { |
| 70 | return sk->s_seq_next++; |
| 71 | } |
| 72 | |
| 73 | /** |
| 74 | * Disable automatic request for ACK |
| 75 | * @arg sk Netlink socket. |
| 76 | * |
| 77 | * The default behaviour of a socket is to request an ACK for |
| 78 | * each message sent to allow for the caller to synchronize to |
| 79 | * the completion of the netlink operation. This function |
| 80 | * disables this behaviour and will result in requests being |
| 81 | * sent which will not have the NLM_F_ACK flag set automatically. |
| 82 | * However, it is still possible for the caller to set the |
| 83 | * NLM_F_ACK flag explicitely. |
| 84 | */ |
| 85 | static inline void nl_socket_disable_auto_ack(struct nl_sock *sk) |
| 86 | { |
| 87 | sk->s_flags |= NL_NO_AUTO_ACK; |
| 88 | } |
| 89 | |
| 90 | /** |
| 91 | * Enable automatic request for ACK (default) |
| 92 | * @arg sk Netlink socket. |
| 93 | * @see nl_socket_disable_auto_ack |
| 94 | */ |
| 95 | static inline void nl_socket_enable_auto_ack(struct nl_sock *sk) |
| 96 | { |
| 97 | sk->s_flags &= ~NL_NO_AUTO_ACK; |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * @name Source Idenficiation |
| 102 | * @{ |
| 103 | */ |
| 104 | |
| 105 | static inline uint32_t nl_socket_get_local_port(struct nl_sock *sk) |
| 106 | { |
| 107 | return sk->s_local.nl_pid; |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * Join multicast groups (deprecated) |
| 112 | * @arg sk Netlink socket. |
| 113 | * @arg groups Bitmask of groups to join. |
| 114 | * |
| 115 | * This function defines the old way of joining multicast group which |
| 116 | * has to be done prior to calling nl_connect(). It works on any kernel |
| 117 | * version but is very limited as only 32 groups can be joined. |
| 118 | */ |
| 119 | static inline void nl_join_groups(struct nl_sock *sk, int groups) |
| 120 | { |
| 121 | sk->s_local.nl_groups |= groups; |
| 122 | } |
| 123 | |
| 124 | /** |
| 125 | * @name Peer Identfication |
| 126 | * @{ |
| 127 | */ |
| 128 | |
| 129 | static inline uint32_t nl_socket_get_peer_port(struct nl_sock *sk) |
| 130 | { |
| 131 | return sk->s_peer.nl_pid; |
| 132 | } |
| 133 | |
| 134 | static inline void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port) |
| 135 | { |
| 136 | sk->s_peer.nl_pid = port; |
| 137 | } |
| 138 | |
| 139 | /** @} */ |
| 140 | |
| 141 | /** |
| 142 | * @name File Descriptor |
| 143 | * @{ |
| 144 | */ |
| 145 | |
| 146 | static inline int nl_socket_get_fd(struct nl_sock *sk) |
| 147 | { |
| 148 | return sk->s_fd; |
| 149 | } |
| 150 | |
| 151 | /** |
| 152 | * Enable use of MSG_PEEK when reading from socket |
| 153 | * @arg sk Netlink socket. |
| 154 | */ |
| 155 | static inline void nl_socket_enable_msg_peek(struct nl_sock *sk) |
| 156 | { |
| 157 | sk->s_flags |= NL_MSG_PEEK; |
| 158 | } |
| 159 | |
| 160 | /** |
| 161 | * Disable use of MSG_PEEK when reading from socket |
| 162 | * @arg sk Netlink socket. |
| 163 | */ |
| 164 | static inline void nl_socket_disable_msg_peek(struct nl_sock *sk) |
| 165 | { |
| 166 | sk->s_flags &= ~NL_MSG_PEEK; |
| 167 | } |
| 168 | |
| 169 | /** |
| 170 | * @name Callback Handler |
| 171 | * @{ |
| 172 | */ |
| 173 | |
| 174 | static inline struct nl_cb *nl_socket_get_cb(struct nl_sock *sk) |
| 175 | { |
| 176 | return nl_cb_get(sk->s_cb); |
| 177 | } |
| 178 | |
| 179 | static inline void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb) |
| 180 | { |
| 181 | nl_cb_put(sk->s_cb); |
| 182 | sk->s_cb = nl_cb_get(cb); |
| 183 | } |
| 184 | |
| 185 | /** |
| 186 | * Modify the callback handler associated to the socket |
| 187 | * @arg sk Netlink socket. |
| 188 | * @arg type which type callback to set |
| 189 | * @arg kind kind of callback |
| 190 | * @arg func callback function |
| 191 | * @arg arg argument to be passwd to callback function |
| 192 | * |
| 193 | * @see nl_cb_set |
| 194 | */ |
| 195 | static inline int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, |
| 196 | enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, |
| 197 | void *arg) |
| 198 | { |
| 199 | return nl_cb_set(sk->s_cb, type, kind, func, arg); |
| 200 | } |
| 201 | |
| 202 | /** @} */ |
| 203 | |
| 204 | static inline int nl_socket_add_membership(struct nl_sock *sk, int group) |
| 205 | { |
| 206 | return nl_socket_add_memberships(sk, group, 0); |
| 207 | } |
| 208 | |
| 209 | |
| 210 | static inline int nl_socket_drop_membership(struct nl_sock *sk, int group) |
| 211 | { |
| 212 | return nl_socket_drop_memberships(sk, group, 0); |
| 213 | } |
| 214 | |
| 215 | |
| 216 | |
| 217 | #ifdef __cplusplus |
| 218 | } |
| 219 | #endif |
| 220 | |
| 221 | #endif |
| 222 | |