libnetfilter_log  1.0.1
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 
31 struct nlmsghdr *
32 nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t qnum)
33 {
34  struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
35  struct nfgenmsg *nfg;
36 
37  nlh->nlmsg_type = (NFNL_SUBSYS_ULOG << 8) | type;
38  nlh->nlmsg_flags = NLM_F_REQUEST;
39 
40  nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
41  nfg->nfgen_family = family;
42  nfg->version = NFNETLINK_V0;
43  nfg->res_id = htons(qnum);
44 
45  return nlh;
46 }
47 
57 int nflog_attr_put_cfg_mode(struct nlmsghdr *nlh, uint8_t mode, uint32_t range)
58 {
59  struct nfulnl_msg_config_mode nfmode = {
60  .copy_mode = mode,
61  .copy_range = htonl(range)
62  };
63 
64  mnl_attr_put(nlh, NFULA_CFG_MODE, sizeof(nfmode), &nfmode);
65 
66  /* it may returns -1 in future */
67  return 0;
68 }
69 
78 int nflog_attr_put_cfg_cmd(struct nlmsghdr *nlh, uint8_t cmd)
79 {
80  struct nfulnl_msg_config_cmd nfcmd = {
81  .command = cmd
82  };
83 
84  mnl_attr_put(nlh, NFULA_CFG_CMD, sizeof(nfcmd), &nfcmd);
85 
86  /* it may returns -1 in future */
87  return 0;
88 }
89 
90 static int nflog_parse_attr_cb(const struct nlattr *attr, void *data)
91 {
92  const struct nlattr **tb = data;
93  int type = mnl_attr_get_type(attr);
94 
95  /* skip unsupported attribute in user-space */
96  if (mnl_attr_type_valid(attr, NFULA_MAX) < 0)
97  return MNL_CB_OK;
98 
99  switch(type) {
100  case NFULA_HWTYPE: /* hardware type */
101  case NFULA_HWLEN: /* hardware header length */
102  if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
103  return MNL_CB_ERROR;
104  break;
105  case NFULA_MARK: /* __u32 nfmark */
106  case NFULA_IFINDEX_INDEV: /* __u32 ifindex */
107  case NFULA_IFINDEX_OUTDEV: /* __u32 ifindex */
108  case NFULA_IFINDEX_PHYSINDEV: /* __u32 ifindex */
109  case NFULA_IFINDEX_PHYSOUTDEV: /* __u32 ifindex */
110  case NFULA_UID: /* user id of socket */
111  case NFULA_SEQ: /* instance-local sequence number */
112  case NFULA_SEQ_GLOBAL: /* global sequence number */
113  case NFULA_GID: /* group id of socket */
114  case NFULA_CT_INFO: /* enum ip_conntrack_info */
115  if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
116  return MNL_CB_ERROR;
117  break;
118  case NFULA_PACKET_HDR:
119  if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
120  sizeof(struct nfulnl_msg_packet_hdr)) < 0) {
121  return MNL_CB_ERROR;
122  }
123  break;
124  case NFULA_TIMESTAMP: /* nfulnl_msg_packet_timestamp */
125  if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
126  sizeof(struct nfulnl_msg_packet_timestamp)) < 0) {
127  return MNL_CB_ERROR;
128  }
129  break;
130  case NFULA_HWADDR: /* nfulnl_msg_packet_hw */
131  if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
132  sizeof(struct nfulnl_msg_packet_hw)) < 0) {
133  return MNL_CB_ERROR;
134  }
135  break;
136  case NFULA_PREFIX: /* string prefix */
137  if (mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0)
138  return MNL_CB_ERROR;
139  break;
140  case NFULA_HWHEADER: /* hardware header */
141  case NFULA_PAYLOAD: /* opaque data payload */
142  case NFULA_CT: /* nf_conntrack_netlink.h */
143  break;
144  }
145  tb[type] = attr;
146  return MNL_CB_OK;
147 }
148 
157 int nflog_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)
158 {
159  return mnl_attr_parse(nlh, sizeof(struct nfgenmsg),
160  nflog_parse_attr_cb, attr);
161 }
162 
191 int nflog_nlmsg_snprintf(char *buf, size_t bufsiz, const struct nlmsghdr *nlh,
192  struct nlattr **attr, enum nflog_output_type type,
193  uint32_t flags)
194 {
195  /* This is a hack to re-use the existing old API code. */
196  struct nflog_data nfad = {
197  .nfa = (struct nfattr **)&attr[1],
198  };
199  int ret;
200 
201  switch (type) {
202  case NFLOG_OUTPUT_XML:
203  ret = nflog_snprintf_xml(buf, bufsiz, &nfad, flags);
204  break;
205  default:
206  ret = -1;
207  errno = EOPNOTSUPP;
208  break;
209  }
210  return ret;
211 }
212 
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:191
int nflog_attr_put_cfg_cmd(struct nlmsghdr *nlh, uint8_t cmd)
Definition: nlmsg.c:78
int nflog_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)
Definition: nlmsg.c:157
struct nlmsghdr * nflog_nlmsg_put_header(char *buf, uint8_t type, uint8_t family, uint16_t qnum)
Definition: nlmsg.c:32
int nflog_attr_put_cfg_mode(struct nlmsghdr *nlh, uint8_t mode, uint32_t range)
Definition: nlmsg.c:57
int nflog_snprintf_xml(char *buf, size_t rem, struct nflog_data *tb, int flags)