Linux网络协议栈从应用层到内核层①

1、socket系统调用源码剖析

系统调用原型

int socket(int domain, int type, int protocol);

domain:表示协议族,在Linux系统中,有很多个协议族,比如IPv4的协议族为AF_INET,IPv6的协议族为AF_INET6,从字面意思上看,domain是int类型的,那它在内核层面是如何帮我们定位到特定协议族的代码呢?这个问题后面再谈

Linux下所有的协议族

       Name                Purpose                          
       AF_UNIX, AF_LOCAL   Local communication              
       AF_INET             IPv4 Internet protocols          
       AF_INET6            IPv6 Internet protocols          
       AF_IPX              IPX - Novell protocols
       AF_NETLINK          Kernel user interface device     
       AF_X25              ITU-T X.25 / ISO-8208 protocol   
       AF_AX25             Amateur radio AX.25 protocol
       AF_ATMPVC           Access to raw ATM PVCs
       AF_APPLETALK        Appletalk                       
       AF_PACKET           Low level packet interface  

type:表示通信的语义,最常见的就是SOCK_STREAM和SOCK_DGRAM,除了这两个比较常见为,还有其他的协议族,可以自行使用man手册查看

在这里插入图片描述

protocol:表示一个传输层协议号,传输层的协议包括IPPROTO_TCP,IPPROTO_UDP;或者对于SOCK_RAW来讲,它是一个通配协议号IPPROTO_IP,用于通配网络层的附属协议ICMP,IGMP等。对于传输层协议来讲,IPPROTO_TCP对应的套接字类型总是SOCK_STREAM,IPPRTO_UDP对应的套接字类型总是STREAM_DGRAM,所以在socket系统调用时,可以不必指定协议号,而直接使用通配符IPPROTO_IP

比如创建一个tcp的套接字:int sockfd = socket(AF_INET, SOCK_STREAM, 0);
这里的0就表示默认使用tcp,不同的协用不同的数字表明,在in.h中定义了内核中所有协议号

enum {
   
  IPPROTO_IP = 0,		/* Dummy protocol for TCP		*/
#define IPPROTO_IP		IPPROTO_IP
  IPPROTO_ICMP = 1,		/* Internet Control Message Protocol	*/
#define IPPROTO_ICMP		IPPROTO_ICMP
  IPPROTO_IGMP = 2,		/* Internet Group Management Protocol	*/
#define IPPROTO_IGMP		IPPROTO_IGMP
  IPPROTO_IPIP = 4,		/* IPIP tunnels (older KA9Q tunnels use 94) */
#define IPPROTO_IPIP		IPPROTO_IPIP
  IPPROTO_TCP = 6,		/* Transmission Control Protocol	*/
#define IPPROTO_TCP		IPPROTO_TCP
  IPPROTO_EGP = 8,		/* Exterior Gateway Protocol		*/
#define IPPROTO_EGP		IPPROTO_EGP
  IPPROTO_PUP = 12,		/* PUP protocol				*/
#define IPPROTO_PUP		IPPROTO_PUP
  IPPROTO_UDP = 17,		/* User Datagram Protocol		*/
#define IPPROTO_UDP		IPPROTO_UDP
  IPPROTO_IDP = 22,		/* XNS IDP protocol			*/
#define IPPROTO_IDP		IPPROTO_IDP
  IPPROTO_TP = 29,		/* SO Transport Protocol Class 4	*/
#define IPPROTO_TP		IPPROTO_TP
  IPPROTO_DCCP = 33,		/* Datagram Congestion Control Protocol */
#define IPPROTO_DCCP		IPPROTO_DCCP
  IPPROTO_IPV6 = 41,		/* IPv6-in-IPv4 tunnelling		*/
#define IPPROTO_IPV6		IPPROTO_IPV6
  IPPROTO_RSVP = 46,		/* RSVP Protocol			*/
#define IPPROTO_RSVP		IPPROTO_RSVP
  IPPROTO_GRE = 47,		/* Cisco GRE tunnels (rfc 1701,1702)	*/
#define IPPROTO_GRE		IPPROTO_GRE
  IPPROTO_ESP = 50,		/* Encapsulation Security Payload protocol */
#define IPPROTO_ESP		IPPROTO_ESP
  IPPROTO_AH = 51,		/* Authentication Header protocol	*/
#define IPPROTO_AH		IPPROTO_AH
  IPPROTO_MTP = 92,		/* Multicast Transport Protocol		*/
#define IPPROTO_MTP		IPPROTO_MTP
  IPPROTO_BEETPH = 94,		/* IP option pseudo header for BEET	*/
#define IPPROTO_BEETPH		IPPROTO_BEETPH
  IPPROTO_ENCAP = 98,		/* Encapsulation Header			*/
#define IPPROTO_ENCAP		IPPROTO_ENCAP
  IPPROTO_PIM = 103,		/* Protocol Independent Multicast	*/
#define IPPROTO_PIM		IPPROTO_PIM
  IPPROTO_COMP = 108,		/* Compression Header Protocol		*/
#define IPPROTO_COMP		IPPROTO_COMP
  IPPROTO_SCTP = 132,		/* Stream Control Transport Protocol	*/
#define IPPROTO_SCTP		IPPROTO_SCTP
  IPPROTO_UDPLITE = 136,	/* UDP-Lite (RFC 3828)			*/
#define IPPROTO_UDPLITE		IPPROTO_UDPLITE
  IPPROTO_MPLS = 137,		/* MPLS in IP (RFC 4023)		*/
#define IPPROTO_MPLS		IPPROTO_MPLS
  IPPROTO_RAW = 255,		/* Raw IP packets			*/
#define IPPROTO_RAW		IPPROTO_RAW
  IPPROTO_MAX
};

2、struct socket 是如何创建的

socket系统调用源码:

SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
   
	int retval;//返回值
	struct socket *sock;//struct socket主要用于给上层提供接口,会跟文件系统相关联
						//后续还会有一个结构体:struct sock,它主要用于向下对接协议栈
	int flags;

	//做一些检测
	BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
	BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK);
	BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK);
	BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK);

	flags = type & ~SOCK_TYPE_MASK;
	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值