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

📄 mydevinet.c

📁 一个基于linux的TCP/IP协议栈的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#define MY_IN_DEV_PROMOTE_SECONDARIES(in_dev)	\	(myipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries)static struct notifier_block *myinetaddr_chain;static void mydevinet_sysctl_register(struct in_device *in_dev,                                        struct ipv4_devconf *p);static void mydevinet_sysctl_unregister(struct ipv4_devconf *p);static void myrtmsg_ifa(int event, struct in_ifaddr* ifa);void myip_mc_up(struct in_device *in_dev);void myip_mc_down(struct in_device *in_dev);void myip_mc_init_dev(struct in_device *in_dev);struct ipv4_devconf myipv4_devconf = {	.accept_redirects = 1,	.send_redirects =  1,	.secure_redirects = 1,	.shared_media =	  1,};static struct ipv4_devconf myipv4_devconf_dflt = {	.accept_redirects =  1,	.send_redirects =    1,	.secure_redirects =  1,	.shared_media =	     1,	.accept_source_route = 1,};static __inline__ int myinet_abc_len(u32 addr){	int rc = -1;	if (ZERONET(addr))		rc = 0;	else{		addr = ntohl(addr);		if (IN_CLASSA(addr))			rc = 8;		else if (IN_CLASSB(addr))			rc = 16;		else if (IN_CLASSC(addr))			rc = 24;	}	return rc;}struct in_device *myinetdev_by_index(int ifindex){	struct net_device *dev;	struct in_device *in_dev = NULL;	read_lock(&dev_base_lock);	dev = __dev_get_by_index(ifindex);	if (dev)		in_dev = in_dev_get(dev);	read_unlock(&dev_base_lock);	return in_dev;}static u32 myconfirm_addr_indev(struct in_device *in_dev, u32 dst,				u32 local, int scope){	int same = 0;	u32 addr = 0;	for_ifa(in_dev) {		if (!addr &&		    (local == ifa->ifa_local || !local) &&		    ifa->ifa_scope <= scope) {			addr = ifa->ifa_local;			if (same)				break;		}		if (!same) {			same = (!local || inet_ifa_match(local, ifa)) &&				(!dst || inet_ifa_match(dst, ifa));			if (same && addr) {				if (local || !dst)					break;				if (inet_ifa_match(addr, ifa))					break;				if (ifa->ifa_scope <= scope) {					addr = ifa->ifa_local;					break;				}				same = 0;			}		}	} endfor_ifa(in_dev);	return same? addr : 0;}u32 myinet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope){	u32 addr = 0;	struct in_device *in_dev;	if (dev) {		rcu_read_lock();		if ((in_dev = __in_dev_get_rcu(dev)))			addr = myconfirm_addr_indev(in_dev, dst, local, scope);		rcu_read_unlock();		return addr;	}	read_lock(&dev_base_lock);	rcu_read_lock();	for (dev = dev_base; dev; dev = dev->next) {		if ((in_dev = __in_dev_get_rcu(dev))) {			addr = myconfirm_addr_indev(in_dev, dst, local, scope);			if (addr)				break;		}	}	rcu_read_unlock();	read_unlock(&dev_base_lock);	return addr;}int myinet_addr_onlink(struct in_device *in_dev, u32 a, u32 b){	rcu_read_lock();	for_primary_ifa(in_dev) {		if (inet_ifa_match(a, ifa)) {			if (!b || inet_ifa_match(b, ifa)) {				rcu_read_unlock();				return 1;			}		}	} endfor_ifa(in_dev);	rcu_read_unlock();	return 0;}u32 myinet_select_addr(const struct net_device *dev, u32 dst, int scope){	u32 addr = 0;	struct in_device *in_dev;	rcu_read_lock();	in_dev = __in_dev_get_rcu(dev);	if (!in_dev)		goto no_in_dev;	for_primary_ifa(in_dev) {		if (ifa->ifa_scope > scope)			continue;		if (!dst || inet_ifa_match(dst, ifa)) {			addr = ifa->ifa_local;			break;		}		if (!addr)			addr = ifa->ifa_local;	} endfor_ifa(in_dev);no_in_dev:	rcu_read_unlock();	if (addr)		goto out;	read_lock(&dev_base_lock);	rcu_read_lock();	for (dev = dev_base; dev; dev = dev->next) {		if ((in_dev = __in_dev_get_rcu(dev)) == NULL)			continue;		for_primary_ifa(in_dev) {			if (ifa->ifa_scope != RT_SCOPE_LINK &&			    ifa->ifa_scope <= scope) {				addr = ifa->ifa_local;				goto out_unlock_both;			}		} endfor_ifa(in_dev);	}out_unlock_both:	read_unlock( &dev_base_lock );	rcu_read_unlock();out:	return addr;}static int mydevinet_sysctl_forward(ctl_table *ctl, int write,				  struct file* filp, void __user *buffer,				  size_t *lenp, loff_t *ppos){	return 0;}int myipv4_doint_and_flush(ctl_table *ctl, int write,			 struct file* filp, void __user *buffer,			 size_t *lenp, loff_t *ppos){	return 0;}int myipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,				  void __user *oldval, size_t __user *oldlenp,				  void __user *newval, size_t newlen, 				  void **context){	return 0;}#define NET_MYIPV4		18static struct mydevinet_sysctl_table{	struct ctl_table_header *sysctl_header;	ctl_table		devinet_vars[__NET_IPV4_CONF_MAX];	ctl_table		devinet_dev[2];	ctl_table		devinet_conf_dir[2];	ctl_table		devinet_proto_dir[2];	ctl_table		devinet_root_dir[2];} mydevinet_sysctl = {	.devinet_vars = {		{			.ctl_name	= NET_IPV4_CONF_FORWARDING,			.procname	= "forwarding",			.data		= &myipv4_devconf.forwarding,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &mydevinet_sysctl_forward,		},		{			.ctl_name	= NET_IPV4_CONF_MC_FORWARDING,			.procname	= "mc_forwarding",			.data		= &myipv4_devconf.mc_forwarding,			.maxlen		= sizeof(int),			.mode		= 0444,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_ACCEPT_REDIRECTS,			.procname	= "accept_redirects",			.data		= &myipv4_devconf.accept_redirects,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_SECURE_REDIRECTS,			.procname	= "secure_redirects",			.data		= &myipv4_devconf.secure_redirects,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_SHARED_MEDIA,			.procname	= "shared_media",			.data		= &myipv4_devconf.shared_media,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_RP_FILTER,			.procname	= "rp_filter",			.data		= &myipv4_devconf.rp_filter,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_SEND_REDIRECTS,			.procname	= "send_redirects",			.data		= &myipv4_devconf.send_redirects,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,			.procname	= "accept_source_route",			.data		= &myipv4_devconf.accept_source_route,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_PROXY_ARP,			.procname	= "proxy_arp",			.data		= &myipv4_devconf.proxy_arp,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_MEDIUM_ID,			.procname	= "medium_id",			.data		= &myipv4_devconf.medium_id,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_BOOTP_RELAY,			.procname	= "bootp_relay",			.data		= &myipv4_devconf.bootp_relay,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_LOG_MARTIANS,			.procname	= "log_martians",			.data		= &myipv4_devconf.log_martians,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_TAG,			.procname	= "tag",			.data		= &myipv4_devconf.tag,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_ARPFILTER,			.procname	= "arp_filter",			.data		= &myipv4_devconf.arp_filter,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_ARP_ANNOUNCE,			.procname	= "arp_announce",			.data		= &myipv4_devconf.arp_announce,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_ARP_IGNORE,			.procname	= "arp_ignore",			.data		= &myipv4_devconf.arp_ignore,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_IPV4_CONF_NOXFRM,			.procname	= "disable_xfrm",			.data		= &myipv4_devconf.no_xfrm,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &myipv4_doint_and_flush,			.strategy	= &myipv4_doint_and_flush_strategy,		},		{			.ctl_name	= NET_IPV4_CONF_NOPOLICY,			.procname	= "disable_policy",			.data		= &myipv4_devconf.no_policy,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &myipv4_doint_and_flush,			.strategy	= &myipv4_doint_and_flush_strategy,		},		{			.ctl_name	= NET_IPV4_CONF_FORCE_IGMP_VERSION,			.procname	= "force_igmp_version",			.data		= &myipv4_devconf.force_igmp_version,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &myipv4_doint_and_flush,			.strategy	= &myipv4_doint_and_flush_strategy,		},		{			.ctl_name	= NET_IPV4_CONF_PROMOTE_SECONDARIES,			.procname	= "promote_secondaries",			.data		= &myipv4_devconf.promote_secondaries,			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &myipv4_doint_and_flush,			.strategy	= &myipv4_doint_and_flush_strategy,		},	},	.devinet_dev = {		{			.ctl_name	= NET_PROTO_CONF_ALL,			.procname	= "all",			.mode		= 0555,			.child		= mydevinet_sysctl.devinet_vars,		},	},	.devinet_conf_dir = {	        {			.ctl_name	= NET_IPV4_CONF,			.procname	= "conf",			.mode		= 0555,			.child		= mydevinet_sysctl.devinet_dev,		},	},	.devinet_proto_dir = {		{			.ctl_name	= NET_MYIPV4,			.procname	= "myipv4",			.mode		= 0555,			.child 		= mydevinet_sysctl.devinet_conf_dir,		},	},	.devinet_root_dir = {		{			.ctl_name	= CTL_NET,			.procname 	= "net",			.mode		= 0555,			.child		= mydevinet_sysctl.devinet_proto_dir,		},	},};static void myinetdev_destroy(struct in_device *in_dev){}static int myinet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg){	return 0;}static int myinet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg){	return 0;}static int myinet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb){	return 0;}int myinet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg){	return 0;}int myinet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg){	return 0;}int myinet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg){	return 0;}int myinet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb){	return 0;}int myinet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg){	return 0;}int myinet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg){	return 0;}int myinet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb){	return 0;}static struct rtnetlink_link myinet_rtnetlink_table[RTM_NR_MSGTYPES] = {	[RTM_NEWADDR  - RTM_BASE] = { .doit	= myinet_rtm_newaddr,	},	[RTM_DELADDR  - RTM_BASE] = { .doit	= myinet_rtm_deladdr,	},	[RTM_GETADDR  - RTM_BASE] = { .dumpit	= myinet_dump_ifaddr,	},	[RTM_NEWROUTE - RTM_BASE] = { .doit	= myinet_rtm_newroute,	},	[RTM_DELROUTE - RTM_BASE] = { .doit	= myinet_rtm_delroute,	},	[RTM_GETROUTE - RTM_BASE] = { .doit	= myinet_rtm_getroute,				      .dumpit	= myinet_dump_fib,	},#ifdef CONFIG_IP_MULTIPLE_TABLES	[RTM_NEWRULE  - RTM_BASE] = { .doit	= myinet_rtm_newrule,	},	[RTM_DELRULE  - RTM_BASE] = { .doit	= myinet_rtm_delrule,	},	[RTM_GETRULE  - RTM_BASE] = { .dumpit	= myinet_dump_rules,	},#endif};static void myinet_rcu_free_ifa(struct rcu_head *head){	struct in_ifaddr *ifa = container_of(head, struct in_ifaddr, rcu_head);	if (ifa->ifa_dev)		in_dev_put(ifa->ifa_dev);	kfree(ifa);}static inline void myinet_free_ifa(struct in_ifaddr *ifa){	call_rcu(&ifa->rcu_head, myinet_rcu_free_ifa);}static int myinet_insert_ifa(struct in_ifaddr *ifa){	struct in_device *in_dev = ifa->ifa_dev;	struct in_ifaddr *ifa1, **ifap, **last_primary;	ASSERT_RTNL();	if (!ifa->ifa_local) {		myinet_free_ifa(ifa);		return 0;	}	ifa->ifa_flags &= ~IFA_F_SECONDARY;	last_primary = &in_dev->ifa_list;	for(ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL; ifap = &ifa1->ifa_next){		if(!(ifa1->ifa_flags & IFA_F_SECONDARY) && ifa->ifa_scope <= ifa1->ifa_scope)			last_primary = &ifa1->ifa_next;		if(ifa1->ifa_mask == ifa->ifa_mask && inet_ifa_match(ifa1->ifa_address, ifa)) {			if (ifa1->ifa_local == ifa->ifa_local){				myinet_free_ifa(ifa);				return -EEXIST;			}			if (ifa1->ifa_scope != ifa->ifa_scope){				myinet_free_ifa(ifa);				return -EINVAL;			}			ifa->ifa_flags |= IFA_F_SECONDARY;		}	}	if (!(ifa->ifa_flags & IFA_F_SECONDARY)) {		net_srandom(ifa->ifa_local);		ifap = last_primary;	}		ifa->ifa_next = *ifap;	*ifap = ifa;	myrtmsg_ifa(RTM_NEWADDR, ifa);	notifier_call_chain(&myinetaddr_chain, NETDEV_UP, ifa);	return 0;}static void myinetdev_changename(struct net_device *dev, struct in_device *in_dev)

⌨️ 快捷键说明

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