libnl
3.2.3
|
00001 /* 00002 * lib/netfilter/nfnl.c Netfilter Netlink 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> 00010 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> 00011 * Copyright (c) 2007 Secure Computing Corporation 00012 */ 00013 00014 /** 00015 * @defgroup nfnl Netfilter Netlink 00016 * 00017 * @par Message Format 00018 * @code 00019 * <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) ---> 00020 * +----------------------------+- - -+- - - - - - - - - - -+- - -+ 00021 * | Header | Pad | Payload | Pad | 00022 * | struct nlmsghdr | | | | 00023 * +----------------------------+- - -+- - - - - - - - - - -+- - -+ 00024 * @endcode 00025 * @code 00026 * <-------- NFNL_HDRLEN ---------> 00027 * +--------------------------+- - -+------------+ 00028 * | Netfilter Netlink Header | Pad | Attributes | 00029 * | struct nfgenmsg | | | 00030 * +--------------------------+- - -+------------+ 00031 * nfnlmsg_attrdata(nfg, hdrlen)-----^ 00032 * @endcode 00033 * 00034 * @par 1) Creating a new netfilter netlink message 00035 * @code 00036 * struct nl_msg *msg; 00037 * 00038 * // Create a new empty netlink message 00039 * msg = nlmsg_alloc(); 00040 * 00041 * // Append the netlink and netfilter netlink message header 00042 * hdr = nfnlmsg_put(msg, PID, SEQ, SUBSYS, TYPE, NLM_F_ECHO, 00043 * FAMILY, RES_ID); 00044 * 00045 * // Append the attributes. 00046 * nla_put_u32(msg, 1, 0x10); 00047 * 00048 * // Message is ready to be sent. 00049 * nl_send_auto_complete(sk, msg); 00050 * 00051 * // All done? Free the message. 00052 * nlmsg_free(msg); 00053 * @endcode 00054 * 00055 * @par 2) Sending of trivial messages 00056 * @code 00057 * // For trivial messages not requiring any subsys specific header or 00058 * // attributes, nfnl_send_simple() may be used to send messages directly. 00059 * nfnl_send_simple(sk, SUBSYS, TYPE, 0, FAMILY, RES_ID); 00060 * @endcode 00061 * @{ 00062 */ 00063 00064 #include <netlink-local.h> 00065 #include <netlink/netlink.h> 00066 #include <netlink/netfilter/nfnl.h> 00067 00068 /** 00069 * @name Socket Creating 00070 * @{ 00071 */ 00072 00073 /** 00074 * Create and connect netfilter netlink socket. 00075 * @arg sk Netlink socket. 00076 * 00077 * Creates a NETLINK_NETFILTER netlink socket, binds the socket and 00078 * issues a connection attempt. 00079 * 00080 * @see nl_connect() 00081 * 00082 * @return 0 on success or a negative error code. 00083 */ 00084 int nfnl_connect(struct nl_sock *sk) 00085 { 00086 return nl_connect(sk, NETLINK_NETFILTER); 00087 } 00088 00089 /** @} */ 00090 00091 /** 00092 * @name Sending 00093 * @{ 00094 */ 00095 00096 /** 00097 * Send trivial netfilter netlink message 00098 * @arg sk Netlink socket. 00099 * @arg subsys_id nfnetlink subsystem 00100 * @arg type nfnetlink message type 00101 * @arg flags message flags 00102 * @arg family nfnetlink address family 00103 * @arg res_id nfnetlink resource id 00104 * 00105 * @return Newly allocated netlink message or NULL. 00106 */ 00107 int nfnl_send_simple(struct nl_sock *sk, uint8_t subsys_id, uint8_t type, 00108 int flags, uint8_t family, uint16_t res_id) 00109 { 00110 struct nfgenmsg hdr = { 00111 .nfgen_family = family, 00112 .version = NFNETLINK_V0, 00113 .res_id = htons(res_id), 00114 }; 00115 00116 return nl_send_simple(sk, NFNLMSG_TYPE(subsys_id, type), flags, 00117 &hdr, sizeof(hdr)); 00118 } 00119 00120 /** @} */ 00121 00122 /** 00123 * @name Message Parsing 00124 * @{ 00125 */ 00126 00127 /** 00128 * Get netfilter subsystem id from message 00129 * @arg nlh netlink messsage header 00130 */ 00131 uint8_t nfnlmsg_subsys(struct nlmsghdr *nlh) 00132 { 00133 return NFNL_SUBSYS_ID(nlh->nlmsg_type); 00134 } 00135 00136 /** 00137 * Get netfilter message type from message 00138 * @arg nlh netlink messsage header 00139 */ 00140 uint8_t nfnlmsg_subtype(struct nlmsghdr *nlh) 00141 { 00142 return NFNL_MSG_TYPE(nlh->nlmsg_type); 00143 } 00144 00145 /** 00146 * Get netfilter family from message 00147 * @arg nlh netlink messsage header 00148 */ 00149 uint8_t nfnlmsg_family(struct nlmsghdr *nlh) 00150 { 00151 struct nfgenmsg *nfg = nlmsg_data(nlh); 00152 00153 return nfg->nfgen_family; 00154 } 00155 00156 /** 00157 * Get netfilter resource id from message 00158 * @arg nlh netlink messsage header 00159 */ 00160 uint16_t nfnlmsg_res_id(struct nlmsghdr *nlh) 00161 { 00162 struct nfgenmsg *nfg = nlmsg_data(nlh); 00163 00164 return ntohs(nfg->res_id); 00165 } 00166 00167 /** @} */ 00168 00169 /** 00170 * @name Message Building 00171 * @{ 00172 */ 00173 00174 static int nfnlmsg_append(struct nl_msg *msg, uint8_t family, uint16_t res_id) 00175 { 00176 struct nfgenmsg *nfg; 00177 00178 nfg = nlmsg_reserve(msg, sizeof(*nfg), NLMSG_ALIGNTO); 00179 if (nfg == NULL) 00180 return -NLE_NOMEM; 00181 00182 nfg->nfgen_family = family; 00183 nfg->version = NFNETLINK_V0; 00184 nfg->res_id = htons(res_id); 00185 NL_DBG(2, "msg %p: Added nfnetlink header family=%d res_id=%d\n", 00186 msg, family, res_id); 00187 return 0; 00188 } 00189 00190 /** 00191 * Allocate a new netfilter netlink message 00192 * @arg subsys_id nfnetlink subsystem 00193 * @arg type nfnetlink message type 00194 * @arg flags message flags 00195 * @arg family nfnetlink address family 00196 * @arg res_id nfnetlink resource id 00197 * 00198 * @return Newly allocated netlink message or NULL. 00199 */ 00200 struct nl_msg *nfnlmsg_alloc_simple(uint8_t subsys_id, uint8_t type, int flags, 00201 uint8_t family, uint16_t res_id) 00202 { 00203 struct nl_msg *msg; 00204 00205 msg = nlmsg_alloc_simple(NFNLMSG_TYPE(subsys_id, type), flags); 00206 if (msg == NULL) 00207 return NULL; 00208 00209 if (nfnlmsg_append(msg, family, res_id) < 0) 00210 goto nla_put_failure; 00211 00212 return msg; 00213 00214 nla_put_failure: 00215 nlmsg_free(msg); 00216 return NULL; 00217 } 00218 00219 /** 00220 * Add netlink and netfilter netlink headers to netlink message 00221 * @arg msg netlink message 00222 * @arg pid netlink process id 00223 * @arg seq sequence number of message 00224 * @arg subsys_id nfnetlink subsystem 00225 * @arg type nfnetlink message type 00226 * @arg flags message flags 00227 * @arg family nfnetlink address family 00228 * @arg res_id nfnetlink resource id 00229 */ 00230 int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, 00231 uint8_t subsys_id, uint8_t type, int flags, uint8_t family, 00232 uint16_t res_id) 00233 { 00234 struct nlmsghdr *nlh; 00235 00236 nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags); 00237 if (nlh == NULL) 00238 return -NLE_MSGSIZE; 00239 00240 return nfnlmsg_append(msg, family, res_id); 00241 } 00242 00243 /** @} */ 00244 00245 /** @} */