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

📄 af_inet.c

📁 linux下arp查询的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		goto out_permanent;	/* Add the new entry after the last permanent entry if any, so that	 * the new entry does not override a permanent entry when matched with	 * a wild-card protocol. But it is allowed to override any existing	 * non-permanent entry.  This means that when we remove this entry, the	 * system automatically returns to the old behavior.	 */	list_add_rcu(&p->list, last_perm);out:	spin_unlock_bh(&inetsw_lock);	synchronize_net();	return;out_permanent:	printk(KERN_ERR "Attempt to override permanent protocol %d.\n",	       protocol);	goto out;out_illegal:	printk(KERN_ERR	       "Ignoring attempt to register invalid socket type %d.\n",	       p->type);	goto out;}void inet_unregister_protosw(struct inet_protosw *p){	if (INET_PROTOSW_PERMANENT & p->flags) {		printk(KERN_ERR		       "Attempt to unregister permanent protocol %d.\n",		       p->protocol);	} else {		spin_lock_bh(&inetsw_lock);		list_del_rcu(&p->list);		spin_unlock_bh(&inetsw_lock);		synchronize_net();	}}/* *      Shall we try to damage output packets if routing dev changes? */int sysctl_ip_dynaddr __read_mostly;static int inet_sk_reselect_saddr(struct sock *sk){	struct inet_sock *inet = inet_sk(sk);	int err;	struct rtable *rt;	__be32 old_saddr = inet->saddr;	__be32 new_saddr;	__be32 daddr = inet->daddr;	if (inet->opt && inet->opt->srr)		daddr = inet->opt->faddr;	/* Query new route. */	err = ip_route_connect(&rt, daddr, 0,			       RT_CONN_FLAGS(sk),			       sk->sk_bound_dev_if,			       sk->sk_protocol,			       inet->sport, inet->dport, sk, 0);	if (err)		return err;	sk_setup_caps(sk, &rt->u.dst);	new_saddr = rt->rt_src;	if (new_saddr == old_saddr)		return 0;	if (sysctl_ip_dynaddr > 1) {		printk(KERN_INFO "%s(): shifting inet->"				 "saddr from %d.%d.%d.%d to %d.%d.%d.%d\n",		       __FUNCTION__,		       NIPQUAD(old_saddr),		       NIPQUAD(new_saddr));	}	inet->saddr = inet->rcv_saddr = new_saddr;	/*	 * XXX The only one ugly spot where we need to	 * XXX really change the sockets identity after	 * XXX it has entered the hashes. -DaveM	 *	 * Besides that, it does not check for connection	 * uniqueness. Wait for troubles.	 */	__sk_prot_rehash(sk);	return 0;}int inet_sk_rebuild_header(struct sock *sk){	struct inet_sock *inet = inet_sk(sk);	struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);	__be32 daddr;	int err;	/* Route is OK, nothing to do. */	if (rt)		return 0;	/* Reroute. */	daddr = inet->daddr;	if (inet->opt && inet->opt->srr)		daddr = inet->opt->faddr;{	struct flowi fl = {		.oif = sk->sk_bound_dev_if,		.nl_u = {			.ip4_u = {				.daddr	= daddr,				.saddr	= inet->saddr,				.tos	= RT_CONN_FLAGS(sk),			},		},		.proto = sk->sk_protocol,		.uli_u = {			.ports = {				.sport = inet->sport,				.dport = inet->dport,			},		},	};	security_sk_classify_flow(sk, &fl);	err = ip_route_output_flow(&rt, &fl, sk, 0);}	if (!err)		sk_setup_caps(sk, &rt->u.dst);	else {		/* Routing failed... */		sk->sk_route_caps = 0;		/*		 * Other protocols have to map its equivalent state to TCP_SYN_SENT.		 * DCCP maps its DCCP_REQUESTING state to TCP_SYN_SENT. -acme		 */		if (!sysctl_ip_dynaddr ||		    sk->sk_state != TCP_SYN_SENT ||		    (sk->sk_userlocks & SOCK_BINDADDR_LOCK) ||		    (err = inet_sk_reselect_saddr(sk)) != 0)			sk->sk_err_soft = -err;	}	return err;}EXPORT_SYMBOL(inet_sk_rebuild_header);static int inet_gso_send_check(struct sk_buff *skb){	struct iphdr *iph;	struct net_protocol *ops;	int proto;	int ihl;	int err = -EINVAL;	if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))		goto out;	iph = skb->nh.iph;	ihl = iph->ihl * 4;	if (ihl < sizeof(*iph))		goto out;	if (unlikely(!pskb_may_pull(skb, ihl)))		goto out;	skb->h.raw = __skb_pull(skb, ihl);	iph = skb->nh.iph;	proto = iph->protocol & (MAX_INET_PROTOS - 1);	err = -EPROTONOSUPPORT;	rcu_read_lock();	ops = rcu_dereference(inet_protos[proto]);	if (likely(ops && ops->gso_send_check))		err = ops->gso_send_check(skb);	rcu_read_unlock();out:	return err;}static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features){	struct sk_buff *segs = ERR_PTR(-EINVAL);	struct iphdr *iph;	struct net_protocol *ops;	int proto;	int ihl;	int id;	if (unlikely(skb_shinfo(skb)->gso_type &		     ~(SKB_GSO_TCPV4 |		       SKB_GSO_UDP |		       SKB_GSO_DODGY |		       SKB_GSO_TCP_ECN |		       0)))		goto out;	if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))		goto out;	iph = skb->nh.iph;	ihl = iph->ihl * 4;	if (ihl < sizeof(*iph))		goto out;	if (unlikely(!pskb_may_pull(skb, ihl)))		goto out;	skb->h.raw = __skb_pull(skb, ihl);	iph = skb->nh.iph;	id = ntohs(iph->id);	proto = iph->protocol & (MAX_INET_PROTOS - 1);	segs = ERR_PTR(-EPROTONOSUPPORT);	rcu_read_lock();	ops = rcu_dereference(inet_protos[proto]);	if (likely(ops && ops->gso_segment))		segs = ops->gso_segment(skb, features);	rcu_read_unlock();	if (!segs || unlikely(IS_ERR(segs)))		goto out;	skb = segs;	do {		iph = skb->nh.iph;		iph->id = htons(id++);		iph->tot_len = htons(skb->len - skb->mac_len);		iph->check = 0;		iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);	} while ((skb = skb->next));out:	return segs;}#ifdef CONFIG_IP_MULTICASTstatic struct net_protocol igmp_protocol = {	.handler =	igmp_rcv,};#endifstatic struct net_protocol tcp_protocol = {	.handler =	tcp_v4_rcv,	.err_handler =	tcp_v4_err,	.gso_send_check = tcp_v4_gso_send_check,	.gso_segment =	tcp_tso_segment,	.no_policy =	1,};static struct net_protocol udp_protocol = {	.handler =	udp_rcv,	.err_handler =	udp_err,	.no_policy =	1,};static struct net_protocol icmp_protocol = {	.handler =	icmp_rcv,};static int __init init_ipv4_mibs(void){	net_statistics[0] = alloc_percpu(struct linux_mib);	net_statistics[1] = alloc_percpu(struct linux_mib);	ip_statistics[0] = alloc_percpu(struct ipstats_mib);	ip_statistics[1] = alloc_percpu(struct ipstats_mib);	icmp_statistics[0] = alloc_percpu(struct icmp_mib);	icmp_statistics[1] = alloc_percpu(struct icmp_mib);	tcp_statistics[0] = alloc_percpu(struct tcp_mib);	tcp_statistics[1] = alloc_percpu(struct tcp_mib);	udp_statistics[0] = alloc_percpu(struct udp_mib);	udp_statistics[1] = alloc_percpu(struct udp_mib);	udplite_statistics[0] = alloc_percpu(struct udp_mib);	udplite_statistics[1] = alloc_percpu(struct udp_mib);	if (!	    (net_statistics[0] && net_statistics[1] && ip_statistics[0]	     && ip_statistics[1] && tcp_statistics[0] && tcp_statistics[1]	     && udp_statistics[0] && udp_statistics[1]	     && udplite_statistics[0] && udplite_statistics[1]             ) )		return -ENOMEM;	(void) tcp_mib_init();	return 0;}static int ipv4_proc_init(void);/* *	IP protocol layer initialiser */static struct packet_type ip_packet_type = {	.type = __constant_htons(ETH_P_IP),	.func = ip_rcv,	.gso_send_check = inet_gso_send_check,	.gso_segment = inet_gso_segment,};static int __init inet_init(void){	struct sk_buff *dummy_skb;	struct inet_protosw *q;	struct list_head *r;	int rc = -EINVAL;	BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb));	rc = proto_register(&tcp_prot, 1);	if (rc)		goto out;	rc = proto_register(&udp_prot, 1);	if (rc)		goto out_unregister_tcp_proto;	rc = proto_register(&raw_prot, 1);	if (rc)		goto out_unregister_udp_proto;	/*	 *	Tell SOCKET that we are alive...	 */	rc = sock_register(&inet_family_ops);	if (rc) {		BUG();	}	/*	 *	Add all the base protocols.	 */	if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)		printk(KERN_CRIT "inet_init: Cannot add ICMP protocol\n");	if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0)		printk(KERN_CRIT "inet_init: Cannot add UDP protocol\n");	if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0)		printk(KERN_CRIT "inet_init: Cannot add TCP protocol\n");#ifdef CONFIG_IP_MULTICAST	if (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0)		printk(KERN_CRIT "inet_init: Cannot add IGMP protocol\n");#endif	/* Register the socket-side information for inet_create. */	for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)		INIT_LIST_HEAD(r);	for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)		inet_register_protosw(q);	/*	 *	Set the ARP module up	 */	arp_init();	/*	 *	Set the IP module up	 */	ip_init();	tcp_v4_init(&inet_family_ops);	/* Setup TCP slab cache for open requests. */	tcp_init();	/* Add UDP-Lite (RFC 3828) */	udplite4_register();	/*	 *	Set the ICMP layer up	 */	icmp_init(&inet_family_ops);	/*	 *	Initialise the multicast router	 */#if defined(CONFIG_IP_MROUTE)	ip_mr_init();#endif	/*	 *	Initialise per-cpu ipv4 mibs	 */	if(init_ipv4_mibs())		printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n"); ;	ipv4_proc_init();	ipfrag_init();	dev_add_pack(&ip_packet_type);	rc = 0;out:	return rc;out_unregister_udp_proto:	proto_unregister(&udp_prot);out_unregister_tcp_proto:	proto_unregister(&tcp_prot);	goto out;}fs_initcall(inet_init);/* ------------------------------------------------------------------------ */#ifdef CONFIG_PROC_FSstatic int __init ipv4_proc_init(void){	int rc = 0;	if (raw_proc_init())		goto out_raw;	if (tcp4_proc_init())		goto out_tcp;	if (udp4_proc_init())		goto out_udp;	if (fib_proc_init())		goto out_fib;	if (ip_misc_proc_init())		goto out_misc;out:	return rc;out_misc:	fib_proc_exit();out_fib:	udp4_proc_exit();out_udp:	tcp4_proc_exit();out_tcp:	raw_proc_exit();out_raw:	rc = -ENOMEM;	goto out;}#else /* CONFIG_PROC_FS */static int __init ipv4_proc_init(void){	return 0;}#endif /* CONFIG_PROC_FS */MODULE_ALIAS_NETPROTO(PF_INET);EXPORT_SYMBOL(inet_accept);EXPORT_SYMBOL(inet_bind);EXPORT_SYMBOL(inet_dgram_connect);EXPORT_SYMBOL(inet_dgram_ops);EXPORT_SYMBOL(inet_getname);EXPORT_SYMBOL(inet_ioctl);EXPORT_SYMBOL(inet_listen);EXPORT_SYMBOL(inet_register_protosw);EXPORT_SYMBOL(inet_release);EXPORT_SYMBOL(inet_sendmsg);EXPORT_SYMBOL(inet_shutdown);EXPORT_SYMBOL(inet_sock_destruct);EXPORT_SYMBOL(inet_stream_connect);EXPORT_SYMBOL(inet_stream_ops);EXPORT_SYMBOL(inet_unregister_protosw);EXPORT_SYMBOL(net_statistics);EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);

⌨️ 快捷键说明

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