Hi, 

I'd like to get your comment about my idea and patches.

Consider you are watching the window of wireshark, and find
storage packet goes out. You may want to identify the process
and its fd where the packet comes.

If the packet is of tcp segment, it is easy to identify the process
and fd. How about raw socket or un-bind udp socket? If we can use
crash of systemtap, we can identify it. However, I think it is nice
if we can identify with packet capture tools.

My initial idea is putting the pid of sender process to socket buffer.
So packet capture tools can know the sender process of each packet.
However, this is meaningless because tcp protocol handler may split
data into multiple socket buffers or join socket buffers into one
socket buffers. Association between process and socket buffers can
be rearranged.

After rethinking I found I can use inode number of socket for my
purpose. See the attachment 
0001-packet-add-socket-inode-number-to-packet-capture-dat.patch.
Combining lsof, we can identify the process and fd.


How do you think the background and idea?

If the header area of af_packet is large enough. I will submit this
patch directly to netdev list. However, it is very limited: only 8
bytes are available. To embed the inode number all 8 bytes are needed.
So I decide to ask the comment here.

0001-Print-inode-number.patch is for netsniff-ng side. This is not
tested.  I also wonder what I should do in user land tool.  First I
look at libpcap. It seems difficult to pass the extra data like inode
numer to the library clients iav libpcap API.

Any suggestions and comments are welcome.
Thanks in advance.

Masatake YAMATO

-- 
You received this message because you are subscribed to the Google Groups 
"netsniff-ng" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
>From 913dfdfc5924a10a35c5f0963a1a84c6edcc1de4 Mon Sep 17 00:00:00 2001
From: Masatake YAMATO <[email protected]>
Date: Sun, 11 May 2014 02:38:56 +0900
Subject: [PATCH] packet: add socket inode number to packet capture data

Signed-off-by: Masatake YAMATO <[email protected]>
---
 include/uapi/linux/if_packet.h |  3 ++-
 net/core/dev.c                 |  7 ++++++-
 net/packet/af_packet.c         | 13 +++++++++++--
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h
index bac27fa..2191b48 100644
--- a/include/uapi/linux/if_packet.h
+++ b/include/uapi/linux/if_packet.h
@@ -99,6 +99,7 @@ struct tpacket_auxdata {
 #define TP_STATUS_VLAN_VALID		(1 << 4) /* auxdata has valid tp_vlan_tci */
 #define TP_STATUS_BLK_TMO		(1 << 5)
 #define TP_STATUS_VLAN_TPID_VALID	(1 << 6) /* auxdata has valid tp_vlan_tpid */
+#define TP_STATUS_SOCKET_INODE          (1 << 7)
 
 /* Tx ring - header status */
 #define TP_STATUS_AVAILABLE	      0
@@ -161,7 +162,7 @@ struct tpacket3_hdr {
 	union {
 		struct tpacket_hdr_variant1 hv1;
 	};
-	__u8		tp_padding[8];
+	__u64		tp_socket_inode;
 };
 
 struct tpacket_bd_ts {
diff --git a/net/core/dev.c b/net/core/dev.c
index 0355ca5..46c514b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1755,9 +1755,14 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 				continue;
 			}
 
+			sock_hold(skb->sk);
 			skb2 = skb_clone(skb, GFP_ATOMIC);
-			if (!skb2)
+			if (!skb2) {
+				sock_put(skb->sk);
 				break;
+			}
+			skb2->sk = skb->sk;
+			skb2->destructor = sock_edemux;
 
 			net_timestamp_set(skb2);
 
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index b85c67c..e761d46 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2009,14 +2009,23 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
 		/* tp_nxt_offset,vlan are already populated above.
 		 * So DONT clear those fields here
 		 */
-		h.h3->tp_status |= status;
 		h.h3->tp_len = skb->len;
 		h.h3->tp_snaplen = snaplen;
 		h.h3->tp_mac = macoff;
 		h.h3->tp_net = netoff;
 		h.h3->tp_sec  = ts.tv_sec;
 		h.h3->tp_nsec = ts.tv_nsec;
-		memset(h.h3->tp_padding, 0, sizeof(h.h3->tp_padding));
+
+		if (skb->sk == NULL ||
+		    skb->sk->sk_socket == NULL ||
+		    test_bit(SOCK_EXTERNALLY_ALLOCATED, &skb->sk->sk_socket->flags)) {
+			memset(&h.h3->tp_socket_inode, 0, sizeof(h.h3->tp_socket_inode));
+		} else {
+			h.h3->tp_socket_inode = SOCK_INODE(skb->sk->sk_socket)->i_ino;
+			status |= TP_STATUS_SOCKET_INODE;
+		}
+		h.h3->tp_status |= status;
+
 		hdrlen = sizeof(*h.h3);
 		break;
 	default:
-- 
1.9.0

>From fadcb7fb6783dda3756862c15adb2c6b255c9bcd Mon Sep 17 00:00:00 2001
From: Masatake YAMATO <[email protected]>
Date: Mon, 26 May 2014 02:52:36 +0900
Subject: [PATCH] Print inode number

---
 dissector.h | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/dissector.h b/dissector.h
index e564697..8e5b334 100644
--- a/dissector.h
+++ b/dissector.h
@@ -53,11 +53,19 @@ static inline void __show_frame_hdr(struct sockaddr_ll *s_ll,
 {
 	char tmp[IFNAMSIZ];
 	union tpacket_uhdr hdr;
+	int inode_available = 0;
+	__uint64 inode = 0LLU;
 
 	if (mode == PRINT_NONE)
 		return;
 
 	hdr.raw = raw;
+
+#ifdef TP_STATUS_SOCKET_INODE
+	inode_available = !!(hdr.h3->tp_status & TP_STATUS_SOCKET_INODE);
+	inode = inode_available? hdr.h3->tp_socket_inode: 0LLU;
+#endif
+
 	switch (mode) {
 	case PRINT_LESS:
 		tprintf("%s %s %u",
@@ -66,13 +74,16 @@ static inline void __show_frame_hdr(struct sockaddr_ll *s_ll,
 			v3 ? hdr.h3->tp_len : hdr.h2->tp_len);
 		break;
 	default:
-		tprintf("%s %s %u %us.%uns %s\n",
+		tprintf("%s %s %u %us.%uns %s %d %llu\n",
 			packet_types[s_ll->sll_pkttype] ? : "?",
 			if_indextoname(s_ll->sll_ifindex, tmp) ? : "?",
 			v3 ? hdr.h3->tp_len : hdr.h2->tp_len,
 			v3 ? hdr.h3->tp_sec : hdr.h2->tp_sec,
 			v3 ? hdr.h3->tp_nsec : hdr.h2->tp_nsec,
-			v3 ? "" : __show_ts_source(hdr.h2->tp_status));
+			v3 ? "" : __show_ts_source(hdr.h2->tp_status),
+			inode_available,
+			inode
+			);
 		break;
 	}
 }
-- 
1.9.0

Reply via email to