📄 profile.c
字号:
#include <linux/config.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/interrupt.h>#include <linux/netdevice.h>#include <linux/string.h>#include <linux/skbuff.h>#include <linux/proc_fs.h>#include <linux/init.h>#include <linux/ip.h>#include <linux/inet.h>#include <net/checksum.h>#include <asm/processor.h>#include <asm/uaccess.h>#include <asm/system.h>#include <net/profile.h>#ifdef CONFIG_NET_PROFILEatomic_t net_profile_active;struct timeval net_profile_adjust;NET_PROFILE_DEFINE(total);struct net_profile_slot *net_profile_chain = &net_prof_total;#ifdef __alpha____u32 alpha_lo;long alpha_hi;static void alpha_tick(unsigned long);static struct timer_list alpha_timer = { NULL, NULL, 0, 0L, alpha_tick };void alpha_tick(unsigned long dummy){ struct timeval dummy_stamp; net_profile_stamp(&dummy_stamp); alpha_timer.expires = jiffies + 4*HZ; add_timer(&alpha_timer);}#endifvoid net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved){ struct net_profile_slot *s; net_profile_sub(entered, leaved); for (s = net_profile_chain; s; s = s->next) { if (s->active) net_profile_add(leaved, &s->irq); }}#ifdef CONFIG_PROC_FSstatic int profile_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data){ off_t pos=0; off_t begin=0; int len=0; struct net_profile_slot *s; len+= sprintf(buffer, "Slot Hits Hi Lo OnIrqHi OnIrqLo Ufl\n"); if (offset == 0) { cli(); net_prof_total.active = 1; atomic_inc(&net_profile_active); NET_PROFILE_LEAVE(total); sti(); } for (s = net_profile_chain; s; s = s->next) { struct net_profile_slot tmp; cli(); tmp = *s; /* Wrong, but pretty close to truth */ s->accumulator.tv_sec = 0; s->accumulator.tv_usec = 0; s->irq.tv_sec = 0; s->irq.tv_usec = 0; s->hits = 0; s->underflow = 0; /* Repair active count, it is possible, only if code has a bug */ if (s->active) { s->active = 0; atomic_dec(&net_profile_active); } sti(); net_profile_sub(&tmp.irq, &tmp.accumulator); len += sprintf(buffer+len,"%-15s %-10d %-10ld %-10lu %-10lu %-10lu %d/%d", tmp.id, tmp.hits, tmp.accumulator.tv_sec, tmp.accumulator.tv_usec, tmp.irq.tv_sec, tmp.irq.tv_usec, tmp.underflow, tmp.active); buffer[len++]='\n'; pos=begin+len; if(pos<offset) { len=0; begin=pos; } if(pos>offset+length) goto done; } *eof = 1;done: *start=buffer+(offset-begin); len-=(offset-begin); if(len>length) len=length; if (len < 0) len = 0; if (offset == 0) { cli(); net_prof_total.active = 0; net_prof_total.hits = 0; net_profile_stamp(&net_prof_total.entered); sti(); } return len;}#endifstruct iphdr whitehole_iph;int whitehole_count;static int whitehole_xmit(struct sk_buff *skb, struct net_device *dev){ struct net_device_stats *stats; stats = (struct net_device_stats *)dev->priv; stats->tx_packets++; stats->tx_bytes+=skb->len; dev_kfree_skb(skb); return 0;}static void whitehole_inject(unsigned long);int whitehole_init(struct net_device *dev);static struct timer_list whitehole_timer = { NULL, NULL, 0, 0L, whitehole_inject };static struct net_device whitehole_dev = { "whitehole", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, whitehole_init, };static int whitehole_open(struct net_device *dev){ whitehole_count = 100000; whitehole_timer.expires = jiffies + 5*HZ; add_timer(&whitehole_timer); return 0;}static int whitehole_close(struct net_device *dev){ del_timer(&whitehole_timer); return 0;}static void whitehole_inject(unsigned long dummy){ struct net_device_stats *stats = (struct net_device_stats *)whitehole_dev.priv; extern int netdev_dropping; do { struct iphdr *iph; struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); if (!skb) break; skb_reserve(skb, 32); iph = (struct iphdr*)skb_put(skb, sizeof(*iph)); skb->mac.raw = ((u8*)iph) - 14; memcpy(iph, &whitehole_iph, sizeof(*iph)); skb->protocol = __constant_htons(ETH_P_IP); skb->dev = &whitehole_dev; skb->pkt_type = PACKET_HOST; stats->rx_packets++; stats->rx_bytes += skb->len; netif_rx(skb); whitehole_count--; } while (netdev_dropping == 0 && whitehole_count>0); if (whitehole_count > 0) { whitehole_timer.expires = jiffies + 1; add_timer(&whitehole_timer); }}static struct net_device_stats *whitehole_get_stats(struct net_device *dev){ struct net_device_stats *stats = (struct net_device_stats *) dev->priv; return stats;}int __init whitehole_init(struct net_device *dev){ dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); if (dev->priv == NULL) return -ENOBUFS; memset(dev->priv, 0, sizeof(struct net_device_stats)); dev->get_stats = whitehole_get_stats; dev->hard_start_xmit = whitehole_xmit; dev->open = whitehole_open; dev->stop = whitehole_close; ether_setup(dev); dev->tx_queue_len = 0; dev->flags |= IFF_NOARP; dev->flags &= ~(IFF_BROADCAST|IFF_MULTICAST); dev->iflink = 0; whitehole_iph.ihl = 5; whitehole_iph.version = 4; whitehole_iph.ttl = 2; whitehole_iph.saddr = in_aton("193.233.7.21"); whitehole_iph.daddr = in_aton("193.233.7.10"); whitehole_iph.tot_len = htons(20); whitehole_iph.check = ip_compute_csum((void *)&whitehole_iph, 20); return 0;}int net_profile_register(struct net_profile_slot *slot){ cli(); slot->next = net_profile_chain; net_profile_chain = slot; sti(); return 0;}int net_profile_unregister(struct net_profile_slot *slot){ struct net_profile_slot **sp, *s; for (sp = &net_profile_chain; (s = *sp) != NULL; sp = &s->next) { if (s == slot) { cli(); *sp = s->next; sti(); return 0; } } return -ESRCH;}int __init net_profile_init(void){ int i;#ifdef CONFIG_PROC_FS create_proc_read_entry("net/profile", 0, 0, profile_read_proc, NULL);#endif register_netdevice(&whitehole_dev); printk("Evaluating net profiler cost ...");#ifdef __alpha__ alpha_tick(0);#endif for (i=0; i<1024; i++) { NET_PROFILE_ENTER(total); NET_PROFILE_LEAVE(total); } if (net_prof_total.accumulator.tv_sec) { printk(" too high!\n"); } else { net_profile_adjust.tv_usec = net_prof_total.accumulator.tv_usec>>10; printk("%ld units\n", net_profile_adjust.tv_usec); } net_prof_total.hits = 0; net_profile_stamp(&net_prof_total.entered); return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -