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 
38 struct nlmsghdr *
39 nflog_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 
64 int 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 
84 int 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 
96 static 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 
162 int 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 
196 int 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
struct nlmsghdr * nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t gnum)
Definition: nlmsg.c:39
int nflog_attr_put_cfg_mode(struct nlmsghdr *nlh, uint8_t mode, uint32_t range)
Definition: nlmsg.c:64