⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proc.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* net/atm/proc.c - ATM /proc interface *//* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA *//* * The mechanism used here isn't designed for speed but rather for convenience * of implementation. We only return one entry per read system call, so we can * be reasonably sure not to overrun the page and race conditions may lead to * the addition or omission of some lines but never to any corruption of a * line's internal structure. * * Making the whole thing slightly more efficient is left as an exercise to the * reader. (Suggestions: wrapper which loops to get several entries per system * call; or make --left slightly more clever to avoid O(n^2) characteristics.) * I find it fast enough on my unloaded 266 MHz Pentium 2 :-) */#include <linux/config.h>#include <linux/module.h> /* for EXPORT_SYMBOL */#include <linux/string.h>#include <linux/types.h>#include <linux/mm.h>#include <linux/fs.h>#include <linux/stat.h>#include <linux/proc_fs.h>#include <linux/errno.h>#include <linux/atm.h>#include <linux/atmdev.h>#include <linux/netdevice.h>#include <linux/atmclip.h>#include <linux/atmarp.h>#include <linux/if_arp.h>#include <linux/init.h> /* for __init */#include <asm/uaccess.h>#include <asm/atomic.h>#include <asm/param.h> /* for HZ */#include "resources.h"#include "common.h" /* atm_proc_init prototype */#include "signaling.h" /* to get sigd - ugly too */#ifdef CONFIG_ATM_CLIP#include <net/atmclip.h>#include "ipcommon.h"extern void clip_push(struct atm_vcc *vcc,struct sk_buff *skb);#endif#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)#include "lec.h"#include "lec_arpc.h"extern struct atm_lane_ops atm_lane_ops; /* in common.c */#endifstatic ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,    loff_t *pos);static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count,    loff_t *pos);static struct file_operations proc_dev_atm_operations = {	read:		proc_dev_atm_read,};static struct file_operations proc_spec_atm_operations = {	read:		proc_spec_atm_read,};static void add_stats(char *buf,const char *aal,  const struct k_atm_aal_stats *stats){	sprintf(strchr(buf,0),"%s ( %d %d %d %d %d )",aal,	    atomic_read(&stats->tx),atomic_read(&stats->tx_err),	    atomic_read(&stats->rx),atomic_read(&stats->rx_err),	    atomic_read(&stats->rx_drop));}static void dev_info(const struct atm_dev *dev,char *buf){	int off,i;	off = sprintf(buf,"%3d %-8s",dev->number,dev->type);	for (i = 0; i < ESI_LEN; i++)		off += sprintf(buf+off,"%02x",dev->esi[i]);	strcat(buf,"  ");	add_stats(buf,"0",&dev->stats.aal0);	strcat(buf,"  ");	add_stats(buf,"5",&dev->stats.aal5);	strcat(buf,"\n");}#ifdef CONFIG_ATM_CLIPstatic int svc_addr(char *buf,struct sockaddr_atmsvc *addr){	static int code[] = { 1,2,10,6,1,0 };	static int e164[] = { 1,8,4,6,1,0 };	int *fields;	int len,i,j,pos;	len = 0;	if (*addr->sas_addr.pub) {		strcpy(buf,addr->sas_addr.pub);		len = strlen(addr->sas_addr.pub);		buf += len;		if (*addr->sas_addr.prv) {			*buf++ = '+';			len++;		}	}	else if (!*addr->sas_addr.prv) {			strcpy(buf,"(none)");			return strlen(buf);		}	if (*addr->sas_addr.prv) {		len += 44;		pos = 0;		fields = *addr->sas_addr.prv == ATM_AFI_E164 ? e164 : code;		for (i = 0; fields[i]; i++) {			for (j = fields[i]; j; j--) {				sprintf(buf,"%02X",addr->sas_addr.prv[pos++]);				buf += 2;			}			if (fields[i+1]) *buf++ = '.';		}	}	return len;}static void atmarp_info(struct net_device *dev,struct atmarp_entry *entry,    struct clip_vcc *clip_vcc,char *buf){	unsigned char *ip;	int svc,off,ip_len;	svc = !clip_vcc || clip_vcc->vcc->family == AF_ATMSVC;	off = sprintf(buf,"%-6s%-4s%-4s%5ld ",dev->name,svc ? "SVC" : "PVC",	    !clip_vcc || clip_vcc->encap ? "LLC" : "NULL",	    (jiffies-(clip_vcc ? clip_vcc->last_use : entry->neigh->used))/	    HZ);	ip = (unsigned char *) &entry->ip;	ip_len = sprintf(buf+off,"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]);	off += ip_len;	while (ip_len++ < 16) buf[off++] = ' ';	if (!clip_vcc)		if (time_before(jiffies, entry->expires))			strcpy(buf+off,"(resolving)\n");		else sprintf(buf+off,"(expired, ref %d)\n",			    atomic_read(&entry->neigh->refcnt));	else if (!svc)			sprintf(buf+off,"%d.%d.%d\n",clip_vcc->vcc->dev->number,			    clip_vcc->vcc->vpi,clip_vcc->vcc->vci);		else {			off += svc_addr(buf+off,&clip_vcc->vcc->remote);			strcpy(buf+off,"\n");		}}#endifstatic void pvc_info(struct atm_vcc *vcc,char *buf){	static const char *class_name[] = { "off","UBR","CBR","VBR","ABR" };	static const char *aal_name[] = {		"---",	"1",	"2",	"3/4",	/*  0- 3 */		"???",	"5",	"???",	"???",	/*  4- 7 */		"???",	"???",	"???",	"???",	/*  8-11 */		"???",	"0",	"???",	"???"};	/* 12-15 */	int off;	off = sprintf(buf,"%3d %3d %5d %-3s %7d %-5s %7d %-6s",	    vcc->dev->number,vcc->vpi,vcc->vci,	    vcc->qos.aal >= sizeof(aal_name)/sizeof(aal_name[0]) ? "err" :	    aal_name[vcc->qos.aal],vcc->qos.rxtp.min_pcr,	    class_name[vcc->qos.rxtp.traffic_class],vcc->qos.txtp.min_pcr,	    class_name[vcc->qos.txtp.traffic_class]);#ifdef CONFIG_ATM_CLIP	if (vcc->push == clip_push) {		struct clip_vcc *clip_vcc = CLIP_VCC(vcc);		struct net_device *dev;		dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;		off += sprintf(buf+off,"CLIP, Itf:%s, Encap:",		    dev ? dev->name : "none?");		if (clip_vcc->encap) off += sprintf(buf+off,"LLC/SNAP");		else off += sprintf(buf+off,"None");	}#endif	strcpy(buf+off,"\n");}static const char *vcc_state(struct atm_vcc *vcc){	static const char *map[] = { ATM_VS2TXT_MAP };	return map[ATM_VF2VS(vcc->flags)];}static void vc_info(struct atm_vcc *vcc,char *buf){	char *here;	here = buf+sprintf(buf,"%p ",vcc);	if (!vcc->dev) here += sprintf(here,"Unassigned    ");	else here += sprintf(here,"%3d %3d %5d ",vcc->dev->number,vcc->vpi,		    vcc->vci);	switch (vcc->family) {		case AF_ATMPVC:			here += sprintf(here,"PVC");			break;		case AF_ATMSVC:			here += sprintf(here,"SVC");			break;		default:			here += sprintf(here,"%3d",vcc->family);	}	here += sprintf(here," %04lx  %5d %7d/%7d %7d/%7d\n",vcc->flags.bits,	    vcc->reply,	    atomic_read(&vcc->tx_inuse),vcc->sk->sndbuf,	    atomic_read(&vcc->rx_inuse),vcc->sk->rcvbuf);}static void svc_info(struct atm_vcc *vcc,char *buf){	char *here;	int i;	if (!vcc->dev)		sprintf(buf,sizeof(void *) == 4 ? "N/A@%p%10s" : "N/A@%p%2s",		    vcc,"");	else sprintf(buf,"%3d %3d %5d         ",vcc->dev->number,vcc->vpi,		    vcc->vci);	here = strchr(buf,0);	here += sprintf(here,"%-10s ",vcc_state(vcc));	here += sprintf(here,"%s%s",vcc->remote.sas_addr.pub,	    *vcc->remote.sas_addr.pub && *vcc->remote.sas_addr.prv ? "+" : "");	if (*vcc->remote.sas_addr.prv)		for (i = 0; i < ATM_ESA_LEN; i++)			here += sprintf(here,"%02x",			    vcc->remote.sas_addr.prv[i]);	strcat(here,"\n");}#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)static char*lec_arp_get_status_string(unsigned char status){  switch(status) {  case ESI_UNKNOWN:    return "ESI_UNKNOWN       ";  case ESI_ARP_PENDING:    return "ESI_ARP_PENDING   ";  case ESI_VC_PENDING:    return "ESI_VC_PENDING    ";  case ESI_FLUSH_PENDING:    return "ESI_FLUSH_PENDING ";  case ESI_FORWARD_DIRECT:    return "ESI_FORWARD_DIRECT";  default:    return "<Unknown>         ";  }}static void lec_info(struct lec_arp_table *entry, char *buf){        int j, offset=0;        for(j=0;j<ETH_ALEN;j++) {                offset+=sprintf(buf+offset,"%2.2x",0xff&entry->mac_addr[j]);        }        offset+=sprintf(buf+offset, " ");        for(j=0;j<ATM_ESA_LEN;j++) {                offset+=sprintf(buf+offset,"%2.2x",0xff&entry->atm_addr[j]);        }        offset+=sprintf(buf+offset, " %s %4.4x",                        lec_arp_get_status_string(entry->status),                        entry->flags&0xffff);        if (entry->vcc) {                offset+=sprintf(buf+offset, "%3d %3d ", entry->vcc->vpi,                                 entry->vcc->vci);                        } else                offset+=sprintf(buf+offset, "        ");        if (entry->recv_vcc) {                offset+=sprintf(buf+offset, "     %3d %3d",                                 entry->recv_vcc->vpi, entry->recv_vcc->vci);        }        sprintf(buf+offset,"\n");}#endifstatic int atm_devices_info(loff_t pos,char *buf){	struct atm_dev *dev;	int left;	if (!pos) {		return sprintf(buf,"Itf Type    ESI/\"MAC\"addr "

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -