관리-도구
편집 파일: ipmib.stp
/* * Copyright (C) 2009 IBM Corp. * Copyright (C) 2010-2018 Red Hat Inc. * * 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. * * Version 1.0 wilder@us.ibm.com 2009-07-06 */ // See the BZ1546179 block comment in tapset/linux/networking.stp for // an explanation of the try/catch statements around sk_buff structure // accesses. %{ /* pure */ #include <net/route.h> #include <linux/skbuff.h> #include <linux/icmp.h> #include <linux/rtnetlink.h> #include <linux/tcp.h> %} /* Commented globals represent statistics that are not supported in this * version. */ global InReceives // global InHdrErrors // global InTooBigErrors global InNoRoutes global InAddrErrors global InUnknownProtos // global InTruncatedPkts global InDiscards // included counts of InHdrErrors InTruncatedPkts // global InDelivers %( kernel_v >= "2.6.24" %? global ForwDatagrams %) global OutRequests // global OutDiscards // global OutNoRoutes global ReasmTimeout global ReasmReqds //global ReasmOKs // global ReasmFails global FragOKs global FragFails // global FragCreates // global InMcastPkts // global OutMcastPkts // global InBcastPkts // global OutBcastPkts /** * sfunction ipmib_remote_addr - Get the remote ip address * @skb: pointer to a struct sk_buff * @SourceIsLocal: flag to indicate whether local operation * * Returns the remote ip address from @skb. */ function ipmib_remote_addr:long (skb:long, SourceIsLocal:long) { iphdr = __get_skb_iphdr(skb); if ( SourceIsLocal ) return ntohl(__ip_skb_daddr(iphdr)); return ntohl(__ip_skb_saddr(iphdr)); } /** * sfunction ipmib_local_addr - Get the local ip address * @skb: pointer to a struct sk_buff * @SourceIsLocal: flag to indicate whether local operation * * Returns the local ip address @skb. */ function ipmib_local_addr:long (skb:long, SourceIsLocal:long) { iphdr = __get_skb_iphdr(skb); if ( SourceIsLocal ) return ntohl(__ip_skb_saddr(iphdr)); return ntohl(__ip_skb_daddr(iphdr)); } /** * sfunction ipmib_tcp_remote_port - Get the remote tcp port * @skb: pointer to a struct sk_buff * @SourceIsLocal: flag to indicate whether local operation * * Returns the remote tcp port from @skb. */ function ipmib_tcp_remote_port:long (skb:long, SourceIsLocal:long) { th = _plunge_into_tcphdr(skb); if ( SourceIsLocal ) return __tcp_skb_dport(th); return __tcp_skb_sport(th); } /** * sfunction ipmib_tcp_local_port - Get the local tcp port * @skb: pointer to a struct sk_buff * @SourceIsLocal: flag to indicate whether local operation * * Returns the local tcp port from @skb. */ function ipmib_tcp_local_port:long (skb:long, SourceIsLocal:long) { th = _plunge_into_tcphdr(skb); if ( SourceIsLocal ) return __tcp_skb_sport(th); return __tcp_skb_dport(th); } /** * sfunction ipmib_get_proto - Get the protocol value * @skb: pointer to a struct sk_buff * * Returns the protocol value from @skb. */ function ipmib_get_proto:long (skb:long) { iphdr = __get_skb_iphdr(skb); return __ip_skb_proto(iphdr); } /* Internal functions */ /* * We can't assume the pointer to the sk_buff->transport_header * has been updated, so we must calculate the value from the network_header. * The caller must verify the skb is for a tcpip packet. */ @__private30 function _plunge_into_tcphdr:long (skb:long) %{ struct sk_buff *skb = (struct sk_buff *)(uintptr_t)STAP_ARG_skb; /* as done by skb_network_header() */ #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,21) STAP_RETVALUE=(long)kread(&(skb->nh.raw)) + (long)sizeof(struct tcphdr); #else #ifdef NET_SKBUFF_DATA_USES_OFFSET STAP_RETVALUE=(long)kread(&(skb->network_header)) + (long)(kread(&(skb->head))) + (long)sizeof(struct tcphdr); #else STAP_RETVALUE=(long)kread(&(skb->network_header)) + (long)sizeof(struct tcphdr); #endif #endif CATCH_DEREF_FAULT(); %} @__private30 function _ehostunreach:long () { return @const("EHOSTUNREACH") } @__private30 function _enetunreach:long () { return @const("ENETUNREACH") } @__private30 function _icmp_dest_unreach:long () { return @const("ICMP_DEST_UNREACH") } @__private30 function _icmp_prot_unreach:long () { return @const("ICMP_PROT_UNREACH") } @__private30 function _net_rx_drop:long () { return @const("NET_RX_DROP") } @__private30 function _icmp_time_exceeded:long () { return @const("ICMP_TIME_EXCEEDED") } @__private30 function _icmp_exc_fragtime:long () { return @const("ICMP_EXC_FRAGTIME") } @__private30 function _rtn_multicast:long () { return @const("RTN_MULTICAST") } @__private30 function _rtn_broadcast:long () { return @const("RTN_BROADCAST") } /** * probe ipmib.InReceives - Count an arriving packet * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @InReceives (equivalent to SNMP's MIB * IPSTATS_MIB_INRECEIVES) */ probe ipmib.InReceives=kernel.function("ip_rcv") { skb = $skb; op = 1; SourceIsLocal = 0; try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) InReceives[key] += op; } /** * probe ipmib.InNoRoutes - Count an arriving packet with no matching socket * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @InNoRoutes (equivalent to SNMP's MIB * IPSTATS_MIB_INNOROUTES) */ probe ipmib.InNoRoutes=kernel.function("ip_route_input_noref").return!, kernel.function("ip_route_input_common").return!, kernel.function("ip_route_input").return { skb = @entry($skb); op = 1; SourceIsLocal = 0; if ( $return != -_enetunreach()) next; try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) InNoRoutes[key] += op; } /** * probe ipmib.InAddrErrors - Count arriving packets with an incorrect address * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @InAddrErrors (equivalent to SNMP's MIB * IPSTATS_MIB_INADDRERRORS) */ probe ipmib.InAddrErrors=kernel.function("ip_route_input_noref").return!, kernel.function("ip_route_input_common").return!, kernel.function("ip_route_input").return { skb = @entry($skb); op = 1; SourceIsLocal = 0; if ( $return != -_ehostunreach()) next; try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) InAddrErrors[key] += op; } /** * probe ipmib.InUnknownProtos - Count arriving packets with an unbound proto * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @InUnknownProtos (equivalent to SNMP's MIB * IPSTATS_MIB_INUNKNOWNPROTOS) */ /* icmp_send() is called by ip_local_deliver_finish() */ probe ipmib.InUnknownProtos=kernel.function("icmp_send") { skb = $skb_in; op = 1; SourceIsLocal = 0; if (($type==_icmp_dest_unreach())&&($code==_icmp_prot_unreach())){ try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) InUnknownProtos[key] += op; } } /** * probe ipmib.InDiscards - Count discarded inbound packets * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @InDiscards (equivalent to SNMP's MIB * STATS_MIB_INDISCARDS) */ /* This stat combines all instances of IPSTATS_MIB_INHDRERRORS, IPSTATS_MIB_INTRUNCATEDPKTS, and STATS_MIB_INDISCARDS. */ probe ipmib.InDiscards=kernel.function("ip_rcv").return { skb = @entry($skb); op = 1; SourceIsLocal = 0; if ( $return != _net_rx_drop() ) next; try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) InDiscards[key] += op; } /** * probe ipmib.ForwDatagrams - Count forwarded packet * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @ForwDatagrams (equivalent to SNMP's MIB * IPSTATS_MIB_OUTFORWDATAGRAMS) */ %( kernel_v >= "2.6.24" %? probe ipmib.ForwDatagrams=kernel.function("ip_forward_finish") { skb = $skb; op = 1; SourceIsLocal = 0; try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) ForwDatagrams[key] += op; } %) /** * probe ipmib.OutRequests - Count a request to send a packet * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @OutRequests (equivalent to SNMP's MIB * IPSTATS_MIB_OUTREQUESTS) */ probe ipmib.OutRequests=kernel.function("ip_output"), kernel.function("ip_mc_output") { skb = @choose_defined($skb, kernel_pointer($pskb)); op = 1; SourceIsLocal = 1; try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) OutRequests[key] += op; } /** * probe ipmib.ReasmTimeout - Count Reassembly Timeouts * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @ReasmTimeout (equivalent to SNMP's MIB * IPSTATS_MIB_REASMTIMEOUT) */ probe ipmib.ReasmTimeout=kernel.function("icmp_send") { skb = $skb_in; op = 0; SourceIsLocal = 1; if(($type==_icmp_time_exceeded())&&($code==_icmp_exc_fragtime())){ try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) ReasmTimeout[key] += op; } } /** * probe ipmib.ReasmReqds - Count number of packet fragments reassembly requests * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @ReasmReqds (equivalent to SNMP's MIB * IPSTATS_MIB_REASMREQDS) */ probe ipmib.ReasmReqds=kernel.function("ip_defrag") { skb = $skb; op = 0; SourceIsLocal = 1; try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) ReasmReqds[key] += op; } /** * probe ipmib.FragOKs - Count datagram fragmented successfully * @skb: pointer to the struct sk_buff being acted on * @op: value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @FragOKs (equivalent to SNMP's MIB * IPSTATS_MIB_FRAGOKS) */ probe ipmib.FragOKs=kernel.function("ip_fragment").return { skb = @entry($skb); op = 1; SourceIsLocal = 1; if ( $return ) next try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) FragOKs [key] += op; } /** * probe ipmib.FragFails - Count datagram fragmented unsuccessfully * @skb: pointer to the struct sk_buff being acted on * @op: Value to be added to the counter (default value of 1) * * The packet pointed to by @skb is filtered by the function * ipmib_filter_key(). If the packet passes the filter is is * counted in the global @FragFails (equivalent to SNMP's MIB * IPSTATS_MIB_FRAGFAILS) */ probe ipmib.FragFails=kernel.function("ip_fragment").return { skb = @entry($skb); op = 1; SourceIsLocal = 1; if (!$return ) next try { key = ipmib_filter_key(skb, op, SourceIsLocal) } catch { } if ( key ) FragFails [key] += op; } @__private30 function _rtn_unspec:long () { return @const("RTN_UNSPEC") } function _input_route_type:long (skb:long) { rt = @choose_defined(@cast(skb, "sk_buff")->_skb_dst, @choose_defined(@cast(skb, "sk_buff")->rtable, 0)) return rt ? @cast(rt, "rtable")->rt_type : _rtn_unspec() } @__private30 function _output_route_type:long (skb:long) { rt = @choose_defined(@cast(skb, "sk_buff")->_skb_dst, @choose_defined(@cast(skb, "sk_buff")->dst, 0)) return rt ? @cast(rt, "rtable")->rt_type : _rtn_unspec() }