build: don't install internal.h
[platform/upstream/libnetfilter_queue.git] / src / nlmsg.c
1 /*
2  * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  */
9 #include <arpa/inet.h>
10 #include <time.h>
11 #include <endian.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include <libmnl/libmnl.h>
16
17 #ifndef __aligned_be64
18 #define __aligned_be64 __be64 __attribute__((aligned(8)))
19 #define __aligned_le64 __le64 __attribute__((aligned(8)))
20 #endif
21
22 #include <linux/netfilter/nfnetlink_queue.h>
23
24 #include <libnetfilter_queue/libnetfilter_queue.h>
25
26 #include "internal.h"
27
28 /**
29  * \defgroup nfq_verd Verdict helpers
30  * @{
31  */
32
33 void nfq_nlmsg_verdict_put(struct nlmsghdr *nlh, int id, int verdict)
34 {
35         struct nfqnl_msg_verdict_hdr vh = {
36                 .verdict        = htonl(verdict),
37                 .id             = htonl(id),
38         };
39         mnl_attr_put(nlh, NFQA_VERDICT_HDR, sizeof(vh), &vh);
40 }
41 EXPORT_SYMBOL(nfq_nlmsg_verdict_put);
42
43 void nfq_nlmsg_verdict_put_mark(struct nlmsghdr *nlh, uint32_t mark)
44 {
45         mnl_attr_put_u32(nlh, NFQA_MARK, htonl(mark));
46 }
47 EXPORT_SYMBOL(nfq_nlmsg_verdict_put_mark);
48
49 void
50 nfq_nlmsg_verdict_put_pkt(struct nlmsghdr *nlh, const void *pkt, uint32_t plen)
51 {
52         mnl_attr_put(nlh, NFQA_PAYLOAD, plen, pkt);
53 }
54 EXPORT_SYMBOL(nfq_nlmsg_verdict_put_pkt);
55
56 /**
57  * @}
58  */
59
60 /**
61  * \defgroup nfq_cfg Config helpers
62  * @{
63  */
64
65 /**
66  * nfq_nlmsg_cfg_build_request- build netlink config message
67  * \param buf Buffer where netlink message is going to be written.
68  * \param cfg Structure that contains the config parameters.
69  * \param command nfqueue nfnetlink command.
70  *
71  * This function returns a pointer to the netlink message. If something goes
72  * wrong it returns NULL.
73  *
74  * Possible commands are:
75  *
76  * - NFQNL_CFG_CMD_NONE: Do nothing. It can be useful to know if the queue
77  *   subsystem is working.
78  * - NFQNL_CFG_CMD_BIND: Binds the program to a specific queue.
79  * - NFQNL_CFG_CMD_UNBIND: Unbinds the program to a specifiq queue.
80  * - NFQNL_CFG_CMD_PF_BIND: Binds to process packets belonging to the given
81  *   protocol family (ie. PF_INET, PF_INET6, etc).
82  * - NFQNL_CFG_CMD_PF_UNBIND: Unbinds from processing packets belonging to the
83  *   given protocol family.
84  */
85 void nfq_nlmsg_cfg_put_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd)
86 {
87         struct nfqnl_msg_config_cmd command = {
88                 .command = cmd,
89                 .pf = htons(pf),
90         };
91         mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(command), &command);
92 }
93 EXPORT_SYMBOL(nfq_nlmsg_cfg_put_cmd);
94
95 void nfq_nlmsg_cfg_put_params(struct nlmsghdr *nlh, uint8_t mode, int range)
96 {
97         struct nfqnl_msg_config_params params = {
98                 .copy_range = htonl(range),
99                 .copy_mode = mode,
100         };
101         mnl_attr_put(nlh, NFQA_CFG_PARAMS, sizeof(params), &params);
102 }
103 EXPORT_SYMBOL(nfq_nlmsg_cfg_put_params);
104
105 void nfq_nlmsg_cfg_put_qmaxlen(struct nlmsghdr *nlh, uint32_t queue_maxlen)
106 {
107         mnl_attr_put_u32(nlh, NFQA_CFG_QUEUE_MAXLEN, htonl(queue_maxlen));
108 }
109 EXPORT_SYMBOL(nfq_nlmsg_cfg_put_qmaxlen);
110
111 /**
112  * @}
113  */
114
115 /**
116  * \defgroup nlmsg Netlink message helper functions
117  * @{
118  */
119
120 static int nfq_pkt_parse_attr_cb(const struct nlattr *attr, void *data)
121 {
122         const struct nlattr **tb = data;
123         int type = mnl_attr_get_type(attr);
124
125         /* skip unsupported attribute in user-space */
126         if (mnl_attr_type_valid(attr, NFQA_MAX) < 0)
127                 return MNL_CB_OK;
128
129         switch(type) {
130         case NFQA_MARK:
131         case NFQA_IFINDEX_INDEV:
132         case NFQA_IFINDEX_OUTDEV:
133         case NFQA_IFINDEX_PHYSINDEV:
134         case NFQA_IFINDEX_PHYSOUTDEV:
135                 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
136                         return MNL_CB_ERROR;
137                 break;
138         case NFQA_TIMESTAMP:
139                 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
140                     sizeof(struct nfqnl_msg_packet_timestamp)) < 0) {
141                         return MNL_CB_ERROR;
142                 }
143                 break;
144         case NFQA_HWADDR:
145                 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
146                     sizeof(struct nfqnl_msg_packet_hw)) < 0) {
147                         return MNL_CB_ERROR;
148                 }
149                 break;
150         case NFQA_PAYLOAD:
151                 break;
152         }
153         tb[type] = attr;
154         return MNL_CB_OK;
155 }
156
157 /**
158  * nfq_pkt_parse - set packet attributes from netlink message
159  * \param nlh netlink message that you want to read.
160  * \param pkt pointer to the packet to set.
161  *
162  * This function returns MNL_CB_ERROR if any error occurs, or MNL_CB_OK on
163  * success.
164  */
165 int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)
166 {
167         return mnl_attr_parse(nlh, sizeof(struct nfgenmsg),
168                               nfq_pkt_parse_attr_cb, attr);
169 }
170 EXPORT_SYMBOL(nfq_nlmsg_parse);
171
172 /**
173  * @}
174  */