Wireshark mailing list archives

Re: Where does libpcap capture frames?


From: Guy Harris <guy () alum mit edu>
Date: Sun, 29 Dec 2013 12:00:48 -0800


On Dec 29, 2013, at 7:50 AM, Stuart Kendrick <stuart.kendrick.sea () gmail com> wrote:

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(),

Or, rather, inside dev_queue_xmit_nit(), the packet is delivered to various sockets, and the sockets libpcap sets up 
are among them.

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

More precisely, ndo_start_xmit is a member of a structure, and contains a pointer to a function and, in the case of 
your network adapter:

 849        .ndo_start_xmit         = e1000_xmit_frame,

it points to e1000_xmit_frame().

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

Well, let's look at the NETDEV_TX_ return values:

        enum netdev_tx {
                __NETDEV_TX_MIN  = INT_MIN,     /* make sure enum is signed */
                NETDEV_TX_OK     = 0x00,        /* driver took care of packet */
                NETDEV_TX_BUSY   = 0x10,        /* driver tx path was busy*/
                NETDEV_TX_LOCKED = 0x20,        /* driver tx lock was already taken */
        };

So if the link is down, it returns "the transmit path wasn't busy and nobody'd taken the lock, so I was able to take 
care of the packet, even if that just meant dropping it on the floor".

Ethernet doesn't guarantee packet delivery, so, if the caller cares whether the packet arrives, it needs to implement a 
protocol that provides acknowledgements, as, for example, TCP does, and retransmit the packet if it doesn't receive an 
acknowledgement in a reasonable amount of time.

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

See above.

(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?

If that's the device on which connection requests to the server should go, it's probably as good a place as any to 
start tracking.

(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?

You might look at SystemTap:

        http://sourceware.org/systemtap/

to see whether you can ask it to report calls to and returns from particular kernel functions, for example.
___________________________________________________________________________
Sent via:    Wireshark-users mailing list <wireshark-users () wireshark org>
Archives:    http://www.wireshark.org/lists/wireshark-users
Unsubscribe: https://wireshark.org/mailman/options/wireshark-users
             mailto:wireshark-users-request () wireshark org?subject=unsubscribe


Current thread: