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

📄 arp.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 3 页
字号:
	kfree_skb(skb);out_of_mem:	return 0;}/* *	User level interface (ioctl, /proc) *//* *	Set (create) an ARP cache entry. */int arp_req_set(struct arpreq *r, struct net_device * dev){	u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;	struct neighbour *neigh;	int err;	if (r->arp_flags&ATF_PUBL) {		u32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr;		if (mask && mask != 0xFFFFFFFF)			return -EINVAL;		if (!dev && (r->arp_flags & ATF_COM)) {			dev = dev_getbyhwaddr(r->arp_ha.sa_family, r->arp_ha.sa_data);			if (!dev)				return -ENODEV;		}		if (mask) {			if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL)				return -ENOBUFS;			return 0;		}		if (dev == NULL) {			ipv4_devconf.proxy_arp = 1;			return 0;		}		if (__in_dev_get(dev)) {			__in_dev_get(dev)->cnf.proxy_arp = 1;			return 0;		}		return -ENXIO;	}	if (r->arp_flags & ATF_PERM)		r->arp_flags |= ATF_COM;	if (dev == NULL) {		struct rtable * rt;		if ((err = ip_route_output(&rt, ip, 0, RTO_ONLINK, 0)) != 0)			return err;		dev = rt->u.dst.dev;		ip_rt_put(rt);		if (!dev)			return -EINVAL;	}	if (r->arp_ha.sa_family != dev->type)			return -EINVAL;	neigh = __neigh_lookup_errno(&arp_tbl, &ip, dev);	err = PTR_ERR(neigh);	if (!IS_ERR(neigh)) {		unsigned state = NUD_STALE;		if (r->arp_flags & ATF_PERM)			state = NUD_PERMANENT;		err = neigh_update(neigh, (r->arp_flags&ATF_COM) ?				   r->arp_ha.sa_data : NULL, state, 1, 0);		neigh_release(neigh);	}	return err;}static unsigned arp_state_to_flags(struct neighbour *neigh){	unsigned flags = 0;	if (neigh->nud_state&NUD_PERMANENT)		flags = ATF_PERM|ATF_COM;	else if (neigh->nud_state&NUD_VALID)		flags = ATF_COM;	return flags;}/* *	Get an ARP cache entry. */static int arp_req_get(struct arpreq *r, struct net_device *dev){	u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;	struct neighbour *neigh;	int err = -ENXIO;	neigh = neigh_lookup(&arp_tbl, &ip, dev);	if (neigh) {		read_lock_bh(&neigh->lock);		memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);		r->arp_flags = arp_state_to_flags(neigh);		read_unlock_bh(&neigh->lock);		r->arp_ha.sa_family = dev->type;		strncpy(r->arp_dev, dev->name, sizeof(r->arp_dev));		neigh_release(neigh);		err = 0;	}	return err;}int arp_req_delete(struct arpreq *r, struct net_device * dev){	int err;	u32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;	struct neighbour *neigh;	if (r->arp_flags & ATF_PUBL) {		u32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr;		if (mask == 0xFFFFFFFF)			return pneigh_delete(&arp_tbl, &ip, dev);		if (mask == 0) {			if (dev == NULL) {				ipv4_devconf.proxy_arp = 0;				return 0;			}			if (__in_dev_get(dev)) {				__in_dev_get(dev)->cnf.proxy_arp = 0;				return 0;			}			return -ENXIO;		}		return -EINVAL;	}	if (dev == NULL) {		struct rtable * rt;		if ((err = ip_route_output(&rt, ip, 0, RTO_ONLINK, 0)) != 0)			return err;		dev = rt->u.dst.dev;		ip_rt_put(rt);		if (!dev)			return -EINVAL;	}	err = -ENXIO;	neigh = neigh_lookup(&arp_tbl, &ip, dev);	if (neigh) {		if (neigh->nud_state&~NUD_NOARP)			err = neigh_update(neigh, NULL, NUD_FAILED, 1, 0);		neigh_release(neigh);	}	return err;}/* *	Handle an ARP layer I/O control request. */int arp_ioctl(unsigned int cmd, void *arg){	int err;	struct arpreq r;	struct net_device * dev = NULL;	switch(cmd) {		case SIOCDARP:		case SIOCSARP:			if (!capable(CAP_NET_ADMIN))				return -EPERM;		case SIOCGARP:			err = copy_from_user(&r, arg, sizeof(struct arpreq));			if (err)				return -EFAULT;			break;		default:			return -EINVAL;	}	if (r.arp_pa.sa_family != AF_INET)		return -EPFNOSUPPORT;	if (!(r.arp_flags & ATF_PUBL) &&	    (r.arp_flags & (ATF_NETMASK|ATF_DONTPUB)))		return -EINVAL;	if (!(r.arp_flags & ATF_NETMASK))		((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr=__constant_htonl(0xFFFFFFFFUL);	rtnl_lock();	if (r.arp_dev[0]) {		err = -ENODEV;		if ((dev = __dev_get_by_name(r.arp_dev)) == NULL)			goto out;		/* Mmmm... It is wrong... ARPHRD_NETROM==0 */		if (!r.arp_ha.sa_family)			r.arp_ha.sa_family = dev->type;		err = -EINVAL;		if ((r.arp_flags & ATF_COM) && r.arp_ha.sa_family != dev->type)			goto out;	} else if (cmd == SIOCGARP) {		err = -ENODEV;		goto out;	}	switch(cmd) {	case SIOCDARP:	        err = arp_req_delete(&r, dev);		break;	case SIOCSARP:		err = arp_req_set(&r, dev);		break;	case SIOCGARP:		err = arp_req_get(&r, dev);		if (!err && copy_to_user(arg, &r, sizeof(r)))			err = -EFAULT;		break;	}out:	rtnl_unlock();	return err;}/* *	Write the contents of the ARP cache to a PROCfs file. */#ifndef CONFIG_PROC_FSstatic int arp_get_info(char *buffer, char **start, off_t offset, int length) { return 0; }#else#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)static char *ax2asc2(ax25_address *a, char *buf);#endif#define HBUFFERLEN 30static int arp_get_info(char *buffer, char **start, off_t offset, int length){	int len=0;	off_t pos=0;	int size;	char hbuffer[HBUFFERLEN];	int i,j,k;	const char hexbuf[] =  "0123456789ABCDEF";	size = sprintf(buffer,"IP address       HW type     Flags       HW address            Mask     Device\n");	pos+=size;	len+=size;	for(i=0; i<=NEIGH_HASHMASK; i++) {		struct neighbour *n;		read_lock_bh(&arp_tbl.lock);		for (n=arp_tbl.hash_buckets[i]; n; n=n->next) {			struct net_device *dev = n->dev;			int hatype = dev->type;			/* Do not confuse users "arp -a" with magic entries */			if (!(n->nud_state&~NUD_NOARP))				continue;			read_lock(&n->lock);/* *	Convert hardware address to XX:XX:XX:XX ... form. */#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)			if (hatype == ARPHRD_AX25 || hatype == ARPHRD_NETROM)				ax2asc2((ax25_address *)n->ha, hbuffer);			else {#endif			for (k=0,j=0;k<HBUFFERLEN-3 && j<dev->addr_len;j++) {				hbuffer[k++]=hexbuf[(n->ha[j]>>4)&15 ];				hbuffer[k++]=hexbuf[n->ha[j]&15     ];				hbuffer[k++]=':';			}			hbuffer[--k]=0;#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)		}#endif			{				char tbuf[16];				sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->primary_key));				size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s"							"     *        %s\n",					tbuf,					hatype,					arp_state_to_flags(n), 					hbuffer,					dev->name);			}			read_unlock(&n->lock);			len += size;			pos += size;		  			if (pos <= offset)				len=0;			if (pos >= offset+length) {				read_unlock_bh(&arp_tbl.lock); 				goto done;			}		}		read_unlock_bh(&arp_tbl.lock);	}	for (i=0; i<=PNEIGH_HASHMASK; i++) {		struct pneigh_entry *n;		for (n=arp_tbl.phash_buckets[i]; n; n=n->next) {			struct net_device *dev = n->dev;			int hatype = dev ? dev->type : 0;			{				char tbuf[16];				sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->key));				size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s"							"     *        %s\n",					tbuf,					hatype, 					ATF_PUBL|ATF_PERM,					"00:00:00:00:00:00",					dev ? dev->name : "*");			}			len += size;			pos += size;		  			if (pos <= offset)				len=0;			if (pos >= offset+length)				goto done;		}	}done:  	*start = buffer+len-(pos-offset);	/* Start of wanted data */	len = pos-offset;			/* Start slop */	if (len>length)		len = length;			/* Ending slop */	if (len<0)		len = 0;	return len;}#endif/* Note, that it is not on notifier chain.   It is necessary, that this routine was called after route cache will be   flushed. */void arp_ifdown(struct net_device *dev){	neigh_ifdown(&arp_tbl, dev);}/* *	Called once on startup. */static struct packet_type arp_packet_type = {	type:	__constant_htons(ETH_P_ARP),	func:	arp_rcv,	data:	(void*) 1, /* understand shared skbs */};void __init arp_init (void){	neigh_table_init(&arp_tbl);	dev_add_pack(&arp_packet_type);	proc_net_create ("arp", 0, arp_get_info);#ifdef CONFIG_SYSCTL	neigh_sysctl_register(NULL, &arp_tbl.parms, NET_IPV4, NET_IPV4_NEIGH, "ipv4");#endif}#ifdef CONFIG_PROC_FS#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)/* *	ax25 -> ASCII conversion */char *ax2asc2(ax25_address *a, char *buf){	char c, *s;	int n;	for (n = 0, s = buf; n < 6; n++) {		c = (a->ax25_call[n] >> 1) & 0x7F;		if (c != ' ') *s++ = c;	}		*s++ = '-';	if ((n = ((a->ax25_call[6] >> 1) & 0x0F)) > 9) {		*s++ = '1';		n -= 10;	}		*s++ = n + '0';	*s++ = '\0';	if (*buf == '\0' || *buf == '-')	   return "*";	return buf;}#endif#endif

⌨️ 快捷键说明

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