Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-users: Re: [Wireshark-users] Where does libpcap capture frames?

From: Stuart Kendrick <stuart.kendrick.sea@xxxxxxxxx>
Date: Sun, 29 Dec 2013 07:50:09 -0800
OK, I think I'm following what you're telling me:

From http://lxr.linux.no/#linux+v3.8/net/core/dev.c
[...]
2361                if (!list_empty(&ptype_all))
2362                        dev_queue_xmit_nit(skb, dev);
2363
2364                skb_len = skb->len;
2365                rc = ops->ndo_start_xmit(skb, dev);
2366                trace_net_dev_xmit(skb, rc, dev, skb_len);
2367                if (rc == NETDEV_TX_OK)
2368                        txq_trans_update(txq);
2369                return rc;
2370        }
2371
2372gso:
2373        do {
[...]

So libpcap gets called somewhere inside dev_queue_xmit_nit(), and since I see the TCP SYNs in the on-board pcap, I conclude that my precious TCP SYNs reach line #2362
Line #2364 is just an assignment ... in Line #2365, we call ndo_start_xmit() with the same arguments we sent to dev_queue_xmit_nit() ... I infer from your comment that ndo_start_xmit() gets implemented inside device drivers
lsmod shows that e1000e is loaded (lspci shows an Intel 82579LM chip set)
Poking through
 846static const struct net_device_ops e1000_netdev_ops = {
 847        .ndo_open               = e1000_open,
 848        .ndo_stop               = e1000_close,
 849        .ndo_start_xmit         = e1000_xmit_frame,

OK, so poking through the e1000e-2.1.4\src, I find this function defined in netdev.c

static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
   struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_ring *tx_ring = adapter->tx_ring;
[...]

And continuing to read ... I am not enjoying what I'm seeing. [Newbie alert: I've written a lot of Perl but I have never touched C ... I have a copy of K&R 2nd edition open in front of me ... structs look like hashes to me ... the 'if' syntax looks familiar ... lines are terminated with semi-colons ... I don't understand #ifdef/#else/#endif yet ... anyway, realize that I may be missing key stuff here, on account of my newness to C]

For example:
if (test_bit(__E1000_DOWN, &adapter->state)) {
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}

## Does this mean that if link is down, return "Yay!  Transmitted successfully" ? --sk

if (skb->len <= 0) {
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;

## Does this mean that if I've been asked to transmit a zero length frame, that I return "Yay!  Transmitted successfully!" ?  --sk

Returning 'success' (NETDEV_TX_OK) when in fact we have not transmitted anything seems lame to me ... furthermore, nowhere do I see anything like:
if (debug) { log_to_syslog("Dang, link is down, so I'm bailing");
or
if (debug) {log_to_syslog("You gave me a zero length frame, so I'm bailing");

(1) Am I on the right track here, poking through e1000_xmit_frame() inside netdev.c, in my search for where my precious TCP SYNs get dropped?

(2) Is there a generic way to ask the kernel to leave tracks in syslog as it transmits frames, to give me clues as to where e1000e is dropping my TCP SYNs?  Or do I have to add the print statements myself, recompile, and reload this module?

--sk