libnetfilter_log 1.0.2
nlmsg.c
1/*
2 * (C) 2015 by Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp>
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 <libmnl/libmnl.h>
11#include <libnetfilter_log/libnetfilter_log.h>
12#include <errno.h>
13#include "internal.h"
14
38struct nlmsghdr *
39nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t gnum)
40{
41 struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
42 struct nfgenmsg *nfg;
43
44 nlh->nlmsg_type = (NFNL_SUBSYS_ULOG << 8) | type;
45 nlh->nlmsg_flags = NLM_F_REQUEST;
46
47 nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
48 nfg->nfgen_family = family;
49 nfg->version = NFNETLINK_V0;
50 nfg->res_id = htons(gnum);
51
52 return nlh;
53}
54
64int nflog_attr_put_cfg_mode(struct nlmsghdr *nlh, uint8_t mode, uint32_t range)
65{
66 struct nfulnl_msg_config_mode nfmode = {
67 .copy_mode = mode,
68 .copy_range = htonl(range)
69 };
70
71 mnl_attr_put(nlh, NFULA_CFG_MODE, sizeof(nfmode), &nfmode);
72
73 /* it may returns -1 in future */
74 return 0;
75}
76
84int nflog_attr_put_cfg_cmd(struct nlmsghdr *nlh, uint8_t cmd)
85{
86 struct nfulnl_msg_config_cmd nfcmd = {
87 .command = cmd
88 };
89
90 mnl_attr_put(nlh, NFULA_CFG_CMD, sizeof(nfcmd), &nfcmd);
91
92 /* it may returns -1 in future */
93 return 0;
94}
95
96static int nflog_parse_attr_cb(const struct nlattr *attr, void *data)
97{
98 const struct nlattr **tb = data;
99 int type = mnl_attr_get_type(attr);
100
101 /* skip unsupported attribute in user-space */
102 if (mnl_attr_type_valid(attr, NFULA_MAX) < 0)
103 return MNL_CB_OK;
104
105 switch(type) {
106 case NFULA_HWTYPE: /* hardware type */
107 case NFULA_HWLEN: /* hardware header length */
108 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
109 return MNL_CB_ERROR;
110 break;
111 case NFULA_MARK: /* __u32 nfmark */
112 case NFULA_IFINDEX_INDEV: /* __u32 ifindex */
113 case NFULA_IFINDEX_OUTDEV: /* __u32 ifindex */
114 case NFULA_IFINDEX_PHYSINDEV: /* __u32 ifindex */
115 case NFULA_IFINDEX_PHYSOUTDEV: /* __u32 ifindex */
116 case NFULA_UID: /* user id of socket */
117 case NFULA_SEQ: /* instance-local sequence number */
118 case NFULA_SEQ_GLOBAL: /* global sequence number */
119 case NFULA_GID: /* group id of socket */
120 case NFULA_CT_INFO: /* enum ip_conntrack_info */
121 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
122 return MNL_CB_ERROR;
123 break;
124 case NFULA_PACKET_HDR:
125 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
126 sizeof(struct nfulnl_msg_packet_hdr)) < 0) {
127 return MNL_CB_ERROR;
128 }
129 break;
130 case NFULA_TIMESTAMP: /* nfulnl_msg_packet_timestamp */
131 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
132 sizeof(struct nfulnl_msg_packet_timestamp)) < 0) {
133 return MNL_CB_ERROR;
134 }
135 break;
136 case NFULA_HWADDR: /* nfulnl_msg_packet_hw */
137 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
138 sizeof(struct nfulnl_msg_packet_hw)) < 0) {
139 return MNL_CB_ERROR;
140 }
141 break;
142 case NFULA_PREFIX: /* string prefix */
143 if (mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0)
144 return MNL_CB_ERROR;
145 break;
146 case NFULA_HWHEADER: /* hardware header */
147 case NFULA_PAYLOAD: /* opaque data payload */
148 case NFULA_CT: /* nf_conntrack_netlink.h */
149 break;
150 }
151 tb[type] = attr;
152 return MNL_CB_OK;
153}
154
162int nflog_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)
163{
164 return mnl_attr_parse(nlh, sizeof(struct nfgenmsg),
165 nflog_parse_attr_cb, attr);
166}
167
196int nflog_nlmsg_snprintf(char *buf, size_t bufsiz, const struct nlmsghdr *nlh,
197 struct nlattr **attr, enum nflog_output_type type,
198 uint32_t flags)
199{
200 /* This is a hack to re-use the existing old API code. */
201 struct nflog_data nfad = {
202 .nfa = (struct nfattr **)&attr[1],
203 };
204 int ret;
205
206 switch (type) {
207 case NFLOG_OUTPUT_XML:
208 ret = nflog_snprintf_xml(buf, bufsiz, &nfad, flags);
209 break;
210 default:
211 ret = -1;
212 errno = EOPNOTSUPP;
213 break;
214 }
215 return ret;
216}
217
int nflog_snprintf_xml(char *buf, size_t rem, struct nflog_data *tb, int flags)
int nflog_nlmsg_snprintf(char *buf, size_t bufsiz, const struct nlmsghdr *nlh, struct nlattr **attr, enum nflog_output_type type, uint32_t flags)
Definition nlmsg.c:196
int nflog_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)
Definition nlmsg.c:162
int nflog_attr_put_cfg_cmd(struct nlmsghdr *nlh, uint8_t cmd)
Definition nlmsg.c:84
int nflog_attr_put_cfg_mode(struct nlmsghdr *nlh, uint8_t mode, uint32_t range)
Definition nlmsg.c:64
struct nlmsghdr * nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t gnum)
Definition nlmsg.c:39