관리-도구
편집 파일: networking.stp
// networking tapset // Copyright (C) 2005, 2006 IBM Corp. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General // Public License (GPL); either version 2, or (at your option) any // later version. // <tapsetdescription> // This family of probe points is used to probe the activities of the network device. // </tapsetdescription> // =================================================================== // // BZ1546179 fix notes. // // The following kernel commit changed the sk_buff structure: // // commit bffa72cf7f9df842f0016ba03586039296b4caaf // Author: Eric Dumazet <edumazet@google.com> // Date: Tue Sep 19 05:14:24 2017 -0700 // // net: sk_buff rbnode reorg // // skb->rbnode shares space with skb->next, skb->prev and skb->tstamp // // The sk_buff structure now looks like this: // // ==== // struct sk_buff { // union { // struct { // /* These two members must be first. */ // struct sk_buff *next; // struct sk_buff *prev; // // union { // struct net_device *dev; // /* Some protocols might use this space to store information, // * while device pointer would be NULL. // * UDP receive path is one user. // */ // unsigned long dev_scratch; // }; // }; // struct rb_node rbnode; /* used in netem & tcp stack */ // }; // ... stuff deleted ... // }; // ==== // // There doesn't seem to be a way by looking at the sk_buf structure // to know which of those union values are valid. If a probe does // something like "dev_name = kernel_string($skb->dev->name)", that // could fail in a variety of ways (since it is difficult to know if // $skb->dev is supposed to be valid). To avoid a probe user getting a // read error (with no way to trap that error), accesses to sk_buff // structs have been surrounded with "try { .. } catch { }" in probes. // // Note that this is done only in probes, not in functions. A user // doing his own probing might want to try to catch an error in a // function himself. // // Also note that statements accessing the same sk_buff structure // field are grouped in a single try/catch statement. Statements // accessing different sk_buff structure fields each have their own // try/catch statement. // // =================================================================== /* A function that returns the device name given the net_device struct */ function get_netdev_name:string (addr:long) { return kernel_string(@cast(addr, "net_device")->name) } /** * probe netdev.receive - Data received from network device. * @dev_name: The name of the device. e.g: eth0, ath1. * @length: The length of the receiving buffer. * @protocol: Protocol of received packet. * */ /// <varlistentry><term>protocol</term> /// <listitem><para>The possible values of protocol could be: /// <table frame='all'><title>Protocol Values</title> /// <tgroup cols='2' align='left' colsep='1' rowsep='1'> /// <colspec colname='Value'/> /// <colspec colname='Protocol'/> /// <thead> /// <row><entry>Value(Hex)</entry><entry>Protocol</entry></row> /// </thead> /// <tbody> /// <row><entry>0001</entry><entry>802.3</entry></row> /// <row><entry>0002</entry><entry>AX.25</entry></row> /// <row><entry>0004</entry><entry>802.2</entry></row> /// <row><entry>0005</entry><entry>SNAP</entry></row> /// <row><entry>0009</entry><entry>Localtalk</entry></row> /// <row><entry>0800</entry><entry>IP</entry></row> /// <row><entry>0805</entry><entry>X.25</entry></row> /// <row><entry>0806</entry><entry>ARP</entry></row> /// <row><entry>8035</entry><entry>RARP</entry></row> /// <row><entry>8100</entry><entry>802.1Q VLAN</entry></row> /// <row><entry>8137</entry><entry>IPX</entry></row> /// <row><entry>86DD</entry><entry>IPv6</entry></row> /// </tbody> /// </tgroup> /// </table> /// </para></listitem> /// </varlistentry> /// /// <varlistentry><term>truesize</term> /// <listitem><para> /// The size of the received data. /// </para></listitem> /// </varlistentry> /// /// </variablelist> ///</para> // Main device receive routine, be called when packet arrives on network device probe netdev.receive = kernel.function("netif_receive_skb_internal") !, kernel.function("netif_receive_skb") { try { dev_name = get_netdev_name($skb->dev) } catch { } try { length = $skb->len } catch { } try { protocol = $skb->protocol } catch { } try { truesize = $skb->truesize } catch { } } /** * probe netdev.transmit - Network device transmitting buffer * @dev_name: The name of the device. e.g: eth0, ath1. * @length: The length of the transmit buffer. * @protocol: The protocol of this packet(defined in include/linux/if_ether.h). * @truesize: The size of the data to be transmitted. * */ // Queue a buffer for transmission to a network device probe netdev.transmit = kernel.function("__dev_queue_xmit") !, kernel.function("dev_queue_xmit") { try { dev_name = get_netdev_name($skb->dev) } catch { } try { length = $skb->len } catch { } try { protocol = $skb->protocol } catch { } try { truesize = $skb->truesize } catch { } } /** * probe netdev.change_mtu - Called when the netdev MTU is changed * @dev_name: The device that will have the MTU changed * @old_mtu: The current MTU * @new_mtu: The new MTU */ probe netdev.change_mtu = kernel.function("dev_set_mtu") { old_mtu = $dev->mtu new_mtu = $new_mtu dev_name = get_netdev_name($dev) } /** * probe netdev.open - Called when the device is opened * @dev_name: The device that is going to be opened */ probe netdev.open = kernel.function("dev_open") { dev_name = get_netdev_name($dev) } /** * probe netdev.close - Called when the device is closed * @dev_name: The device that is going to be closed */ probe netdev.close = kernel.function("dev_close") { dev_name = get_netdev_name($dev) } /** * probe netdev.hard_transmit - Called when the devices is going to TX (hard) * @dev_name: The device scheduled to transmit * @protocol: The protocol used in the transmission * @length: The length of the transmit buffer. * @truesize: The size of the data to be transmitted. */ probe netdev.hard_transmit = kernel.function("dev_hard_start_xmit") ? { dev_name = get_netdev_name($dev) try { protocol = @choose_defined($first, $skb)->protocol } catch { } try { length = @choose_defined($first, $skb)->len } catch { } try { truesize = @choose_defined($first, $skb)->truesize } catch { } } /** * probe netdev.rx - Called when the device is going to receive a packet * @dev_name: The device received the packet * @protocol: The packet protocol */ probe netdev.rx = kernel.function("netif_rx") { try { netdev = $skb->dev dev_name = get_netdev_name(netdev) } catch { } try { protocol = $skb->protocol } catch { } } /** * probe netdev.change_rx_flag - Called when the device RX flag will be changed * @dev_name: The device that will be changed * @flags: The new flags */ probe netdev.change_rx_flag = kernel.function("dev_change_rx_flags") ? { dev_name = (@defined($dev) ? get_netdev_name($dev) : "unknown") flags = @choose_defined($flags, 0) } /** * probe netdev.set_promiscuity - Called when the device enters/leaves promiscuity * @dev_name: The device that is entering/leaving promiscuity mode * @enable: If the device is entering promiscuity mode * @disable: If the device is leaving promiscuity mode * @inc: Count the number of promiscuity openers */ probe netdev.set_promiscuity = kernel.function("dev_set_promiscuity") { dev_name = get_netdev_name($dev) if ($inc){ enable = 1 } else { disable = 1 } inc = $inc } /** * probe netdev.ioctl - Called when the device suffers an IOCTL * @cmd: The IOCTL request * @arg: The IOCTL argument (usually the netdev interface) */ probe netdev.ioctl = kernel.function("dev_ioctl") { cmd = $cmd arg = user_string_quoted(@choose_defined($ifr, $arg)) } /** * probe netdev.register - Called when the device is registered * @dev_name: The device that is going to be registered */ probe netdev.register = kernel.function("register_netdevice"), kernel.function("register_netdev") { dev_name = get_netdev_name($dev) } /** * probe netdev.unregister - Called when the device is being unregistered * @dev_name: The device that is going to be unregistered */ probe netdev.unregister = kernel.function("unregister_netdev") { dev_name = get_netdev_name($dev) } /** * probe netdev.get_stats - Called when someone asks the device statistics * @dev_name: The device that is going to provide the statistics */ probe netdev.get_stats = kernel.function("dev_get_stats") ? { dev_name = get_netdev_name($dev) } /** * probe netdev.change_mac - Called when the netdev_name has the MAC changed * @dev_name: The device that will have the MAC changed * @mac_len: The MAC length * @old_mac: The current MAC address * @new_mac: The new MAC address */ probe netdev.change_mac = kernel.function("dev_set_mac_address") ? { dev_name = get_netdev_name($dev) mac_len = $dev->addr_len // Old MAC Address old_mac = sprintf("%02x:%02x:%02x:%02x:%02x:%02x", $dev->dev_addr[0], $dev->dev_addr[1], $dev->dev_addr[2], $dev->dev_addr[3], $dev->dev_addr[4], $dev->dev_addr[5]) // New MAC Address new_mac = sprintf("%02x:%02x:%02x:%02x:%02x:%02x", $sa->sa_data[0], $sa->sa_data[1], $sa->sa_data[2], $sa->sa_data[3], $sa->sa_data[4], $sa->sa_data[5]) }