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