bsd socket是Berkeley套接字应用程序接口(API)包括了一个用C语言写成的应用程序开发库,主要用于实现进程间通讯,在计算机网络通讯方面被广泛使用。
Berkeley套接字接口的定义在几个头文件中。这些文件的名字和内容与具体的实现之间有些许的不同。 大体上包括:
这个列表是一个Berkeley套接字API库提供的函数或者方法的概要:
socket() 创建一个新的确定类型的套接字,类型用一个整型数值标识,并为它分配系统资源。
bind() 一般用于服务器端,将一个套接字与一个套接字地址结构相关联,比如,一个指定的本地端口和IP地址。
listen() 用于服务器端,使一个绑定的TCP套接字进入监听状态。
connect() 用于客户端,为一个套接字分配一个自由的本地端口号。 如果是TCP套接字的话,它会试图获得一个新的TCP连接。
accept() 用于服务器端。 它接受一个从远端客户端发出的创建一个新的TCP连接的接入请求,创建一个新的套接字,与该连接相应的套接字地址相关联。
send()和recv(),或者write()和read(),或者recvfrom()和sendto(), 用于往/从远程套接字发送和接受数据。
close() 用于系统释放分配给一个套接字的资源。 如果是TCP,连接会被中断。
gethostbyname()和gethostbyaddr() 用于解析主机名和地址.
select() 用于修整有如下情况的套接字列表: 准备读,准备写或者是有错误。
poll() 用于检查套接字的状态。 套接字可以被测试,看是否可以写入、读取或是有错误。
getsockopt() 用于查询指定的套接字一个特定的套接字选项的当前值。
setsockopt() 用于为指定的套接字设定一个特定的套接字选项。
http://zh.wikipedia.org/wiki/Berkeley套接字
协议族是一组协议的集合, 协议栈是协议的实现,指网络中各层协议的总和(有顺序的一组协议), 协议栈的工作原理类似于栈,遵守FIFO的原则。其形象的反映了一个网络中文件传输的过程:由上层协议到底层协议,再由底层协议到上层协议。使用最广泛的是英特网协 议栈,由上到下的协议分别是:应用层(HTTP,TELNET,DNS,EMAIL等),运输层(TCP,UDP),网络层(IP),链路层(WI- FI,以太网,令牌环,FDDI等),物理层.
TCP/IP也称”国际协议簇”, 即不仅指 TCP/IP协议本身,而且包括与其有关的协议。 TCP为传输控制协议,IP为网际协议,是网络层最重要的协议。采用TCP/IP协议通过互联网传送信息可减少网络中的传输阻塞,方便大批量的数据在网上 传输,从而提高网络的传输效率。 TCP/IP协议族中包括上百个互为关联的协议,其中有:Telnet(Remote Login):提供远程登录功能; FTP (FileTransfer Protocol):远程文件传输协议,允许用户将远程主机上的文件拷贝到自己的计算机上; SMTP (Simple Messagetransfer Protocol):简单信息传输协议,主要用于传输电子邮件;NFS(Network File Server):网络文件服务器,可使多台计算机透明地访问彼此的目录 ; UDP ( User DatagramProtocol):用户数据包协议。
BSD socket向用户提供了一个一致性的网络编程接口,他的底层是INET PF_UNIX PF_IPX PF_PACKET PF_INET6 等协议栈。INET socket层是其中的IPv4网络协议的接口,相当于建立了AF_INET形式的socket,该层使用sock结构保存接口上额外的参数,主要的文件有net/ipv4/protocol.c、net/ipv4/af_inet.c和net/core/sock.c。
socket层支持包括TCP/IP协议在内的Internet协议族,一个协议使用另一个协议的服务。它与BSD socket层的接口要通过一系列Internet协议簇,socket操作,这一操作是在网络初始化时就已经注册到BSD socket层的。BSD socket层从已注册的INET proto_ops数据结构中调用INET层socket支持例程来为它执行工作。例如,一个地址族为INET的BSD socket建立请求,将用到下层的INET socket的建立函数。。在这些操作中,BSD socket层把用来描述BSD socket的socket 结构传构到INET层。为了不把BSD socket与TCP/IP的特定信息搞混,INET socket层使用它自己的数据结构 --sock,它与BSD socket结构相连。这意味着后来的INET socket调用能够很容易地重新找到sock结构。sock结构的协议操作指针(sock->sk_prot)也在初始化时建立,它依赖与被请求的协议。如果请求的是TCP,那么sock结构的协议操作指针将指向TCP连接所必需的TCP协议操作集。proto_ops(socket->ops)结构由地址族类型和一系列指向与特定地址族对应的socket操作例程的函数指针组成。
推断:bsd socket层封装了操作inet socket层的函数,inet socket层可以替换成其他协议层,比如pf_packet
实现传输层和网络层的操作,TCP/UDP层使用inet_protocol和proto结构,主要文件有
net/ipv4/udp.c、net/ipv4/datagram.c、net/ipv4/tcp_input.c和net/ipv4/tcp_out.c。ip层使用packet_type结构表示,主要文件包括net/ipv4文件夹下的ip_forward.c,ip_fragment.c,ip_input.c,ip_output.c。
实现网络层操作,该层使用net_device结构表示,主要的文件包括net/core/dev.c和driver/net目录下的所有文件。使用PPP,SLIP,Eethernet协议。
1,收包
^
|--------------bsd socket层---------
| sys_read fs/read_write.c
| sock_read net/socket.c
| sock_recvmsg net/socket.c
|--------------inet socket层(也可以是PF_pocket层)-----------
inet_create
| inet_recvmsg net/ipv4/af_inet.c
| udp_recvmsg net/ipv4/udp.c
| skb_recv_datagram net/core/datagram.c
| ------------------------------------------- 传输层--------
| sock_queue_rcv_skb include/net/sock.h
| udp_queue_rcv_skb net/ipv4/udp.c
| udp_rcv net/ipv4/udp.c
| ip_local_deliver_finish net/ipv4/ip_input.c
| ip_local_deliver net/ipv4/ip_input.c
| ip_recv net/ipv4/ip_input.c
| net_rx_action net/dev.c
| ----------------------------------链路层----------
| netif_rx net/dev.c
| el3_rx driver/net/3c309.c
| el3_interrupt driver/net/3c309.c
如果socket(PF_INET,SOCK_DGRAM,IPPROTO_IP)
|--------------socket
| sys_write fs/read_write.c
| sock_writev net/socket.c
| sock_sendmsg net/socket.c
| inet_sendmsg net/ipv4/af_inet.c
|----------------传输层(协议栈)-----------
| udp_sendmsg net/ipv4/udp.c
| ip_build_xmit net/ipv4/ip_output.c
| output_maybe_reroute net/ipv4/ip_output.c
| ip_output net/ipv4/ip_output.c
| ip_finish_output net/ipv4/ip_output.c
|--------------链路层(网卡驱动)---------------
| dev_queue_xmit net/dev.c
| --------------------------------------------
| el3_start_xmit driver/net/3c309.c
V
推断使用socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
|--------------socket
| sys_write fs/read_write.c
| sock_writev net/socket.c
| sock_sendmsg net/socket.c (sock->ops = &packet_ops_spkt;)
|----------------传输层(协议栈)-----------
|packet_sendmsg_spkt net/packet/af_packet.c
|--------------链路层(网卡驱动)---------------
| dev_queue_xmit net/dev.c
| --------------------------------------------
| el3_start_xmit driver/net/3c309.c
V
1,linux协议栈分析sk_buff的结构分析:
在内核中sk_buff表示一个网络数据包,它是一个双向链表,而链表头就是sk_buff_head,在老的内核里面sk_buff会有一个list域直接指向sk_buff_head也就是链表头,现在在2.6.32里面这个域已经被删除了。
http://simohayha.iteye.com/blog/556168
2,linux协议栈struct sk_buff *skb相关的操作函数
struct sk_buff * skb
skb为要引用的缓冲区
http://blog.csdn.net/jasenwan88/article/details/7365060
3,Linux.协议栈分析.AF_PACKET
当通过socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))来创建处理链路层数据包时,内核会首先调用packet_create创建套接字
http://acm.hrbeu.edu.cn/~puppy/2012/02/09/linux-协议栈分析-af_packet/
4,Linux 网卡驱动相关——01-02-03
http://www.cnblogs.com/zhuyp1015/archive/2012/08/04.html
5.linux内核网络栈代码的准备知识
http://www.cnblogs.com/better-zyy/archive/2012/03/16/2400811.html
6,2.4中PACKET模块代码分析
http://linux.chinaunix.net/techdoc/net/2006/01/18/926921.shtml