1 /* libnfnetlink.h: Header file for generic netfilter netlink interface 2 * 3 * (C) 2002 Harald Welte <laforge@gnumonks.org> 4 * 5 * 2005-10-29 Pablo Neira Ayuso <pablo@netfilter.org>: 6 * Fix NFNL_HEADER_LEN 7 * 2005-11-13 Pablo Neira Ayuso <pablo@netfilter.org>: 8 * Define NETLINK_NETFILTER if it's undefined 9 */ 10 11 #ifndef __LIBNFNETLINK_H 12 #define __LIBNFNETLINK_H 13 14 #ifndef aligned_u64 15 #define aligned_u64 unsigned long long __attribute__((aligned(8))) 16 #endif 17 18 #include <sys/socket.h> /* for sa_family_t */ 19 #include <linux/netlink.h> 20 #include <libnfnetlink/linux_nfnetlink.h> 21 #include <stdbool.h> 22 23 #ifndef NETLINK_NETFILTER 24 #define NETLINK_NETFILTER 12 25 #endif 26 27 #ifndef SOL_NETLINK 28 #define SOL_NETLINK 270 29 #endif 30 31 #ifndef NETLINK_BROADCAST_SEND_ERROR 32 #define NETLINK_BROADCAST_SEND_ERROR 4 33 #endif 34 35 #ifndef NETLINK_NO_ENOBUFS 36 #define NETLINK_NO_ENOBUFS 5 37 #endif 38 39 #define NLMSG_TAIL(nlh) \ 40 (((void *) (nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)) 41 42 #define NFNL_HEADER_LEN (NLMSG_ALIGN(sizeof(struct nlmsghdr)) \ 43 +NLMSG_ALIGN(sizeof(struct nfgenmsg))) 44 45 #define NFNL_BUFFSIZE 8192 46 47 #ifdef __cplusplus 48 extern "C" { 49 #endif 50 51 struct nfnlhdr { 52 struct nlmsghdr nlh; 53 struct nfgenmsg nfmsg; 54 }; 55 56 struct nfnl_callback { 57 int (*call)(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data); 58 void *data; 59 u_int16_t attr_count; 60 }; 61 62 struct nfnl_handle; 63 struct nfnl_subsys_handle; 64 65 extern int nfnl_fd(struct nfnl_handle *h); 66 extern unsigned int nfnl_portid(const struct nfnl_handle *h); 67 68 /* get a new library handle */ 69 extern struct nfnl_handle *nfnl_open(void); 70 extern struct nfnl_handle *nfnl_open2(int fd, bool bind); 71 extern int nfnl_close(struct nfnl_handle *); 72 extern int nfnl_close2(struct nfnl_handle *); 73 74 extern struct nfnl_subsys_handle *nfnl_subsys_open(struct nfnl_handle *, 75 u_int8_t, u_int8_t, 76 unsigned int); 77 extern struct nfnl_subsys_handle *nfnl_subsys_open2(struct nfnl_handle *, 78 u_int8_t, u_int8_t, 79 unsigned int, 80 bool bind); 81 extern void nfnl_subsys_close(struct nfnl_subsys_handle *); 82 83 /* set and unset sequence tracking */ 84 void nfnl_set_sequence_tracking(struct nfnl_handle *h); 85 void nfnl_unset_sequence_tracking(struct nfnl_handle *h); 86 87 /* set receive buffer size (for nfnl_catch) */ 88 extern void nfnl_set_rcv_buffer_size(struct nfnl_handle *h, unsigned int size); 89 90 /* sending of data */ 91 extern int nfnl_send(struct nfnl_handle *, struct nlmsghdr *); 92 extern int nfnl_sendmsg(const struct nfnl_handle *, const struct msghdr *msg, 93 unsigned int flags); 94 extern int nfnl_sendiov(const struct nfnl_handle *nfnlh, 95 const struct iovec *iov, unsigned int num, 96 unsigned int flags); 97 extern void nfnl_fill_hdr(struct nfnl_subsys_handle *, struct nlmsghdr *, 98 unsigned int, u_int8_t, u_int16_t, u_int16_t, 99 u_int16_t); 100 extern __attribute__((deprecated)) int 101 nfnl_talk(struct nfnl_handle *, struct nlmsghdr *, pid_t, 102 unsigned, struct nlmsghdr *, 103 int (*)(struct sockaddr_nl *, struct nlmsghdr *, void *), void *); 104 105 /* simple challenge/response */ 106 extern __attribute__((deprecated)) int 107 nfnl_listen(struct nfnl_handle *, 108 int (*)(struct sockaddr_nl *, struct nlmsghdr *, void *), void *); 109 110 /* receiving */ 111 extern ssize_t nfnl_recv(const struct nfnl_handle *h, unsigned char *buf, size_t len); 112 extern int nfnl_callback_register(struct nfnl_subsys_handle *, 113 u_int8_t type, struct nfnl_callback *cb); 114 extern int nfnl_callback_unregister(struct nfnl_subsys_handle *, u_int8_t type); 115 extern int nfnl_handle_packet(struct nfnl_handle *, char *buf, int len); 116 117 /* parsing */ 118 extern struct nfattr *nfnl_parse_hdr(const struct nfnl_handle *nfnlh, 119 const struct nlmsghdr *nlh, 120 struct nfgenmsg **genmsg); 121 extern int nfnl_check_attributes(const struct nfnl_handle *nfnlh, 122 const struct nlmsghdr *nlh, 123 struct nfattr *tb[]); 124 extern struct nlmsghdr *nfnl_get_msg_first(struct nfnl_handle *h, 125 const unsigned char *buf, 126 size_t len); 127 extern struct nlmsghdr *nfnl_get_msg_next(struct nfnl_handle *h, 128 const unsigned char *buf, 129 size_t len); 130 131 /* callback verdict */ 132 enum { 133 NFNL_CB_FAILURE = -1, /* failure */ 134 NFNL_CB_STOP = 0, /* stop the query */ 135 NFNL_CB_CONTINUE = 1, /* keep iterating */ 136 }; 137 138 /* join a certain netlink multicast group */ 139 extern int nfnl_join(const struct nfnl_handle *nfnlh, unsigned int group); 140 141 /* process a netlink message */ 142 extern int nfnl_process(struct nfnl_handle *h, 143 const unsigned char *buf, 144 size_t len); 145 146 /* iterator API */ 147 148 extern struct nfnl_iterator * 149 nfnl_iterator_create(const struct nfnl_handle *h, 150 const char *buf, 151 size_t len); 152 153 extern void nfnl_iterator_destroy(struct nfnl_iterator *it); 154 155 extern int nfnl_iterator_process(struct nfnl_handle *h, 156 struct nfnl_iterator *it); 157 158 extern int nfnl_iterator_next(const struct nfnl_handle *h, 159 struct nfnl_iterator *it); 160 161 /* replacement for nfnl_listen */ 162 extern int nfnl_catch(struct nfnl_handle *h); 163 164 /* replacement for nfnl_talk */ 165 extern int nfnl_query(struct nfnl_handle *h, struct nlmsghdr *nlh); 166 167 #define nfnl_attr_present(tb, attr) \ 168 (tb[attr-1]) 169 170 #define nfnl_get_data(tb, attr, type) \ 171 ({ type __ret = 0; \ 172 if (tb[attr-1]) \ 173 __ret = *(type *)NFA_DATA(tb[attr-1]); \ 174 __ret; \ 175 }) 176 177 #define nfnl_get_pointer_to_data(tb, attr, type) \ 178 ({ type *__ret = NULL; \ 179 if (tb[attr-1]) \ 180 __ret = NFA_DATA(tb[attr-1]); \ 181 __ret; \ 182 }) 183 184 #ifndef NLA_F_NESTED 185 #define NLA_F_NESTED (1 << 15) 186 #endif 187 188 /* nfnl attribute handling functions */ 189 extern int nfnl_addattr_l(struct nlmsghdr *, int, int, const void *, int); 190 extern int nfnl_addattr8(struct nlmsghdr *, int, int, u_int8_t); 191 extern int nfnl_addattr16(struct nlmsghdr *, int, int, u_int16_t); 192 extern int nfnl_addattr32(struct nlmsghdr *, int, int, u_int32_t); 193 extern int nfnl_nfa_addattr_l(struct nfattr *, int, int, const void *, int); 194 extern int nfnl_nfa_addattr16(struct nfattr *, int, int, u_int16_t); 195 extern int nfnl_nfa_addattr32(struct nfattr *, int, int, u_int32_t); 196 extern int nfnl_parse_attr(struct nfattr **, int, struct nfattr *, int); 197 #define nfnl_parse_nested(tb, max, nfa) \ 198 nfnl_parse_attr((tb), (max), NFA_DATA((nfa)), NFA_PAYLOAD((nfa))) 199 #define nfnl_nest(nlh, bufsize, type) \ 200 ({ struct nfattr *__start = NLMSG_TAIL(nlh); \ 201 nfnl_addattr_l(nlh, bufsize, (NLA_F_NESTED | type), NULL, 0); \ 202 __start; }) 203 #define nfnl_nest_end(nlh, tail) \ 204 ({ (tail)->nfa_len = (void *) NLMSG_TAIL(nlh) - (void *) tail; }) 205 206 extern void nfnl_build_nfa_iovec(struct iovec *iov, struct nfattr *nfa, 207 u_int16_t type, u_int32_t len, 208 unsigned char *val); 209 extern unsigned int nfnl_rcvbufsiz(const struct nfnl_handle *h, 210 unsigned int size); 211 212 213 extern void nfnl_dump_packet(struct nlmsghdr *, int, char *); 214 215 /* 216 * index to interface name API 217 */ 218 219 #ifndef IFNAMSIZ 220 #define IFNAMSIZ 16 221 #endif 222 223 struct nlif_handle; 224 225 struct nlif_handle *nlif_open(void); 226 void nlif_close(struct nlif_handle *orig); 227 int nlif_fd(struct nlif_handle *nlif_handle); 228 int nlif_query(struct nlif_handle *nlif_handle); 229 int nlif_catch(struct nlif_handle *nlif_handle); 230 int nlif_index2name(struct nlif_handle *nlif_handle, 231 unsigned int if_index, 232 char *name); 233 int nlif_get_ifflags(const struct nlif_handle *h, 234 unsigned int index, 235 unsigned int *flags); 236 237 #ifdef __cplusplus 238 } /* extern "C" */ 239 #endif 240 241 /* Pablo: What is the equivalence of be64_to_cpu in userspace? 242 * 243 * Harald: Good question. I don't think there's a standard way [yet?], 244 * so I'd suggest manually implementing it by "#if little endian" bitshift 245 * operations in C (at least for now). 246 * 247 * All the payload of any nfattr will always be in network byte order. 248 * This would allow easy transport over a real network in the future 249 * (e.g. jamal's netlink2). 250 * 251 * Pablo: I've called it __be64_to_cpu instead of be64_to_cpu, since maybe 252 * there will one in the userspace headers someday. We don't want to 253 * pollute POSIX space naming, 254 */ 255 256 #include <byteswap.h> 257 #if __BYTE_ORDER == __BIG_ENDIAN 258 # ifndef __be64_to_cpu 259 # define __be64_to_cpu(x) (x) 260 # endif 261 # else 262 # if __BYTE_ORDER == __LITTLE_ENDIAN 263 # ifndef __be64_to_cpu 264 # define __be64_to_cpu(x) __bswap_64(x) 265 # endif 266 # endif 267 #endif 268 269 #endif /* __LIBNFNETLINK_H */ 270