extern u_int32_t nfq_get_physindev(struct nfq_data *nfad);
extern u_int32_t nfq_get_outdev(struct nfq_data *nfad);
extern u_int32_t nfq_get_physoutdev(struct nfq_data *nfad);
+extern int nfq_get_uid(struct nfq_data *nfad, u_int32_t *uid);
+extern int nfq_get_gid(struct nfq_data *nfad, u_int32_t *gid);
extern int nfq_get_indev_name(struct nlif_handle *nlif_handle,
struct nfq_data *nfad, char *name);
NFQ_XML_PHYSDEV = (1 << 3),
NFQ_XML_PAYLOAD = (1 << 4),
NFQ_XML_TIME = (1 << 5),
+ NFQ_XML_UID = (1 << 6),
+ NFQ_XML_GID = (1 << 7),
NFQ_XML_ALL = ~0U,
};
NFQA_CT_INFO, /* enum ip_conntrack_info */
NFQA_CAP_LEN, /* __u32 length of captured packet */
NFQA_SKB_INFO, /* __u32 skb meta information */
+ NFQA_EXP, /* nf_conntrack_netlink.h */
+ NFQA_UID, /* __u32 sk uid */
+ NFQA_GID, /* __u32 sk gid */
__NFQA_MAX
};
#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
#define NFQA_CFG_F_CONNTRACK (1 << 1)
#define NFQA_CFG_F_GSO (1 << 2)
-#define NFQA_CFG_F_MAX (1 << 3)
+#define NFQA_CFG_F_UID_GID (1 << 3)
+#define NFQA_CFG_F_MAX (1 << 4)
/* flags for NFQA_SKB_INFO */
/* packet appears to have wrong checksums, but they are ok */
NFQA_CT_INFO, /* enum ip_conntrack_info */
NFQA_CAP_LEN, /* __u32 length of captured packet */
NFQA_SKB_INFO, /* __u32 skb meta information */
+ NFQA_EXP, /* nf_conntrack_netlink.h */
+ NFQA_UID, /* __u32 sk uid */
+ NFQA_GID, /* __u32 sk gid */
__NFQA_MAX
};
#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
#define NFQA_CFG_F_CONNTRACK (1 << 1)
#define NFQA_CFG_F_GSO (1 << 2)
-#define NFQA_CFG_F_MAX (1 << 3)
+#define NFQA_CFG_F_UID_GID (1 << 3)
+#define NFQA_CFG_F_MAX (1 << 4)
/* flags for NFQA_SKB_INFO */
/* packet appears to have wrong checksums, but they are ok */
* if this bit is set, the layer 3/4 checksums of the packet appear incorrect,
* but are not (because they will be corrected later by the kernel).
*
+ * - NFQA_CFG_F_UID_GID: the kernel will dump UID and GID of the socket to
+ * which each packet belongs.
+ *
* Here's a little code snippet to show how to use this API:
* \verbatim
uint32_t flags = NFQA_CFG_F_FAIL_OPEN;
EXPORT_SYMBOL(nfq_get_packet_hw);
/**
+ * nfq_get_uid - get the UID of the user the packet belongs to
+ * \param nfad Netlink packet data handle passed to callback function
+ *
+ * \return 1 if there is a UID available, 0 otherwise.
+ */
+int nfq_get_uid(struct nfq_data *nfad, u_int32_t *uid)
+{
+ if (!nfnl_attr_present(nfad->data, NFQA_UID))
+ return 0;
+
+ *uid = ntohl(nfnl_get_data(nfad->data, NFQA_UID, u_int32_t));
+ return 1;
+}
+EXPORT_SYMBOL(nfq_get_uid);
+
+/**
+ * nfq_get_gid - get the GID of the user the packet belongs to
+ * \param nfad Netlink packet data handle passed to callback function
+ *
+ * \return 1 if there is a GID available, 0 otherwise.
+ */
+int nfq_get_gid(struct nfq_data *nfad, u_int32_t *gid)
+{
+ if (!nfnl_attr_present(nfad->data, NFQA_GID))
+ return 0;
+
+ *gid = ntohl(nfnl_get_data(nfad->data, NFQA_GID, u_int32_t));
+ return 1;
+}
+EXPORT_SYMBOL(nfq_get_gid);
+
+/**
* nfq_get_payload - get payload
* \param nfad Netlink packet data handle passed to callback function
* \param data Pointer of pointer that will be pointed to the payload
struct nfqnl_msg_packet_hdr *ph;
struct nfqnl_msg_packet_hw *hwph;
u_int32_t mark, ifi;
+ u_int32_t uid, gid;
int size, offset = 0, len = 0, ret;
unsigned char *data;
SNPRINTF_FAILURE(size, rem, offset, len);
}
+ if (nfq_get_uid(tb, &uid) && (flags & NFQ_XML_UID)) {
+ size = snprintf(buf + offset, rem, "<uid>%u</uid>", uid);
+ SNPRINTF_FAILURE(size, rem, offset, len);
+ }
+
+ if (nfq_get_gid(tb, &gid) && (flags & NFQ_XML_GID)) {
+ size = snprintf(buf + offset, rem, "<gid>%u</gid>", gid);
+ SNPRINTF_FAILURE(size, rem, offset, len);
+ }
+
ret = nfq_get_payload(tb, &data);
if (ret >= 0 && (flags & NFQ_XML_PAYLOAD)) {
int i;