网络-网络接口

208 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

网络协议栈

协议分层(协议栈)

协议分为:
|_______应用层message(数据报文的格式)
|______传输层segment(解决进程接收数据&决定数据传输形式| 使用端口号)
|_____网络层packet(解决数据报文的跨局域网传输| 使用IP地址)
|____链路层frame(解决局域网链路问题| 使用MAC地址)
|___物理层bit(物理层屏蔽了物理层采用的传输介质,通信设备和通信技术的差异性,指定不同类型的物理协议,使得数据链路只需要考虑如何使用物理层的服务,而不用考虑物理层采用了那种传输介质)

网络数据报文封装格式为:[以太网头]+[IP头]+[TCP头]+[应用层数据报文]+[以太网尾]

典型协议:
|___应用层(HTTP,FTP,SMTP,SSH,Telnet,DNS,DHCP)
|___传输层(TCP,UDP)
|___网络层(ICMP[ping],IGMP,IP[v4,v6])
|___链路层(ARP,RARP)

PS:
1. 
   ICMP| IP Control Management Protocol
   IGMP| IP Group Management Protocol
   它们的存在就是为了辅助IP层工作的,ICMP处理IP层出错,IGMP可以帮助一个主机加入一个组播组。
2. 
   ARP 地址解析协议在OSI模型中位于LLC层;TCP/IP模型中位于网络层

网络设备

网络设备
|___交换机switching(交换机在同一时刻可进行多个端口对之间的数据传输)
|___防火墙Firewall(通常指硬件防火墙| 程序嵌入到芯片中以减少CPU负担)
|___网关gateway(工作在OSI网络层| 典型应用是网络专用服务器)
|___路由器Router(工作在OSI网络层| Brouter是网桥和路由器的合并)
|___网桥Bridge(工作在OSI数据链路层| 交换机就是网桥)
|___中继器Repeater(工作在OSI物理层| 集线器HUB是有多个端口的中继器)
PS:
连MAC都不知道的算第1层,例如已经死绝了的hub
只知道MAC不知道IP的算第2层,例如普通交换机
只知道IP不知道port(也就不管TCP还是UDP)的算第3层,例如普通路由器
知道IP还知道port的算第4层,例如 NAT
关心payload的算第7层,例如 http proxy

网络接口socket

内核源码 fs/net.h

struct socket {
	socket_state		state;
	short				type;
	unsigned long		flags;
	struct socket_wq	*wq;
	struct file			*file;
	struct sock			*sk;
	const struct proto_ops	*ops;//函数指针集合
};

参数1| socket_state
typedef enum {
	SS_FREE = 0,			/* not allocated		*/
	SS_UNCONNECTED,			/* unconnected to any socket	*/
	SS_CONNECTING,			/* in process of connecting	*/
	SS_CONNECTED,			/* connected to socket		*/
	SS_DISCONNECTING		/* in process of disconnecting	*/
} socket_state;

参数2| 
参数3| 

参数4| socket_wq
struct socket_wq {
	/* Note: wait MUST be first field of socket_wq */
	wait_queue_head_t	wait;
	struct fasync_struct	*fasync_list;
	unsigned long		flags; /* %SOCKWQ_ASYNC_NOSPACE, etc */
	struct rcu_head		rcu;
} ____cacheline_aligned_in_smp;

参数5| 
参数6| 

参数7| proto_ops
struct proto_ops {
	int		family;
	struct module	*owner;
	int		(*release)   (struct socket *sock);
	int		(*bind)	     (struct socket *sock,
			      struct sockaddr *myaddr,
			      int sockaddr_len);
	int		(*connect)   (struct socket *sock,
			      struct sockaddr *vaddr,
			      int sockaddr_len, int flags);
	int		(*socketpair)(struct socket *sock1,
			      struct socket *sock2);
	int		(*accept)    (struct socket *sock,
			      struct socket *newsock, int flags, bool kern);
	int		(*getname)   (struct socket *sock,
			      struct sockaddr *addr,
			      int peer);
	__poll_t	(*poll)	     (struct file *file, struct socket *sock,
			      struct poll_table_struct *wait);
	int		(*ioctl)     (struct socket *sock, unsigned int cmd,
			      unsigned long arg);
#ifdef CONFIG_COMPAT
	int	 	(*compat_ioctl) (struct socket *sock, unsigned int cmd,
			      unsigned long arg);
#endif
	int		(*listen)    (struct socket *sock, int len);
	int		(*shutdown)  (struct socket *sock, int flags);
	int		(*setsockopt)(struct socket *sock, int level,
			      int optname, char __user *optval, unsigned int optlen);
	int		(*getsockopt)(struct socket *sock, int level,
			      int optname, char __user *optval, int __user *optlen);
#ifdef CONFIG_COMPAT
	int		(*compat_setsockopt)(struct socket *sock, int level,
			      int optname, char __user *optval, unsigned int optlen);
	int		(*compat_getsockopt)(struct socket *sock, int level,
			      int optname, char __user *optval, int __user *optlen);
#endif
	int		(*sendmsg)   (struct socket *sock, struct msghdr *m,
			      size_t total_len);
	/* Notes for implementing recvmsg:
 	* ===============================
 	* msg->msg_namelen should get updated by the recvmsg handlers
 	* iff msg_name != NULL. It is by default 0 to prevent
 	* returning uninitialized memory to user space.  The recvfrom
 	* handlers can assume that msg.msg_name is either NULL or has
 	* a minimum size of sizeof(struct sockaddr_storage).
 	*/
	int		(*recvmsg)   (struct socket *sock, struct msghdr *m,
			      size_t total_len, int flags);
	int		(*mmap)	     (struct file *file, struct socket *sock,
			      struct vm_area_struct * vma);
	ssize_t		(*sendpage)  (struct socket *sock, struct page *page,
			      int offset, size_t size, int flags);
	ssize_t 	(*splice_read)(struct socket *sock,  loff_t *ppos,
			       struct pipe_inode_info *pipe, size_t len, unsigned int flags);
	int		(*set_peek_off)(struct sock *sk, int val);
	int		(*peek_len)(struct socket *sock);

	/* The following functions are called internally by kernel with
 	* sock lock already held.
 	*/
	int		(*read_sock)(struct sock *sk, read_descriptor_t *desc,
			     sk_read_actor_t recv_actor);
	int		(*sendpage_locked)(struct sock *sk, struct page *page,
				   int offset, size_t size, int flags);
	int		(*sendmsg_locked)(struct sock *sk, struct msghdr *msg,
				  size_t size);
	int		(*set_rcvlowat)(struct sock *sk, int val);
};