Home page logo
/

wireshark logo Wireshark mailing list archives

Re: Where does libpcap capture frames?
From: Stuart Kendrick <stuart.kendrick.sea () gmail com>
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 <http://lxr.linux.no/linux+*/net/core/dev.c#L2361>
if (!list_empty
<http://lxr.linux.no/linux+*/+code=list_empty>(&ptype_all
<http://lxr.linux.no/linux+*/+code=ptype_all>))2362
<http://lxr.linux.no/linux+*/net/core/dev.c#L2362>
   dev_queue_xmit_nit
<http://lxr.linux.no/linux+*/+code=dev_queue_xmit_nit>(skb
<http://lxr.linux.no/linux+*/+code=skb>, dev
<http://lxr.linux.no/linux+*/+code=dev>);2363
<http://lxr.linux.no/linux+*/net/core/dev.c#L2363>2364
<http://lxr.linux.no/linux+*/net/core/dev.c#L2364>
skb_len <http://lxr.linux.no/linux+*/+code=skb_len> = skb
<http://lxr.linux.no/linux+*/+code=skb>->len
<http://lxr.linux.no/linux+*/+code=len>;2365
<http://lxr.linux.no/linux+*/net/core/dev.c#L2365>                rc
<http://lxr.linux.no/linux+*/+code=rc> = ops
<http://lxr.linux.no/linux+*/+code=ops>->ndo_start_xmit
<http://lxr.linux.no/linux+*/+code=ndo_start_xmit>(skb
<http://lxr.linux.no/linux+*/+code=skb>, dev
<http://lxr.linux.no/linux+*/+code=dev>);2366
<http://lxr.linux.no/linux+*/net/core/dev.c#L2366>
trace_net_dev_xmit
<http://lxr.linux.no/linux+*/+code=trace_net_dev_xmit>(skb
<http://lxr.linux.no/linux+*/+code=skb>, rc
<http://lxr.linux.no/linux+*/+code=rc>, dev
<http://lxr.linux.no/linux+*/+code=dev>, skb_len
<http://lxr.linux.no/linux+*/+code=skb_len>);2367
<http://lxr.linux.no/linux+*/net/core/dev.c#L2367>                if
(rc <http://lxr.linux.no/linux+*/+code=rc> == NETDEV_TX_OK
<http://lxr.linux.no/linux+*/+code=NETDEV_TX_OK>)2368
<http://lxr.linux.no/linux+*/net/core/dev.c#L2368>
   txq_trans_update
<http://lxr.linux.no/linux+*/+code=txq_trans_update>(txq
<http://lxr.linux.no/linux+*/+code=txq>);2369
<http://lxr.linux.no/linux+*/net/core/dev.c#L2369>
return rc <http://lxr.linux.no/linux+*/+code=rc>;2370
<http://lxr.linux.no/linux+*/net/core/dev.c#L2370>        }2371
<http://lxr.linux.no/linux+*/net/core/dev.c#L2371>2372
<http://lxr.linux.no/linux+*/net/core/dev.c#L2372>gso
<http://lxr.linux.no/linux+*/+code=gso>:2373
<http://lxr.linux.no/linux+*/net/core/dev.c#L2373>        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

 846 <http://lxr.linux.no/linux+*/drivers/net/ethernet/intel/e1000/e1000_main.c#L846>static
const struct net_device_ops
<http://lxr.linux.no/linux+*/+code=net_device_ops> e1000_netdev_ops
<http://lxr.linux.no/linux+*/+code=e1000_netdev_ops> = { 847
<http://lxr.linux.no/linux+*/drivers/net/ethernet/intel/e1000/e1000_main.c#L847>
       .ndo_open <http://lxr.linux.no/linux+*/+code=ndo_open>
     = e1000_open <http://lxr.linux.no/linux+*/+code=e1000_open>, 848
<http://lxr.linux.no/linux+*/drivers/net/ethernet/intel/e1000/e1000_main.c#L848>
       .ndo_stop <http://lxr.linux.no/linux+*/+code=ndo_stop>
     = e1000_close <http://lxr.linux.no/linux+*/+code=e1000_close>,
849 <http://lxr.linux.no/linux+*/drivers/net/ethernet/intel/e1000/e1000_main.c#L849>
       .ndo_start_xmit
<http://lxr.linux.no/linux+*/+code=ndo_start_xmit>         =
e1000_xmit_frame <http://lxr.linux.no/linux+*/+code=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



On Thu, Dec 26, 2013 at 5:48 PM, Guy Harris <guy () alum mit edu> wrote:


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

I've found this neat diagram of the functions called as a frame wends
its way toward hardware (Figure 4 in Section 2.3 in
http://kernelnewbies.org/Networking?action=AttachFile&do=get&target=hacking_the_wholism_of_linux_net.txt)
ending in rtl8169_start_xmit()

From the text, I'm guessing that various 'hooks' can dink with the
frame:  NF_IP_PRE_ROUTING, NF_IP_LOCAL_IN, NF_IP_POST_ROUTING
nowhere in there do I see where libpcap gets its copy

That's because they're not showing the guts of dev_hard_start_xmit() - in
particularly, they're not showing the call to dev_queue_xmit_nit().

==> What functions can mess with a frame as it approaches hardware?
 Obviously, libpcap can register a request for a copy ... what functions
can discard the frame after libpcap gets its copy?

Functions called from the device's ndo_start_xmit routine.

Or the routine itself.
___________________________________________________________________________
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

___________________________________________________________________________
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

  By Date           By Thread  

Current thread:
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]