/* * This structure really needs to be cleaned up. * Most of it is for TCP, and not used by any of * the other protocols. * 大部分功能是为TCP准备的 */ struct sock { struct options *opt;//IP选项缓冲于此处 volatile unsigned long wmem_alloc;//发送缓冲队列中存放的数据的大小,这两个与后面的rcvbuf和sndbuf一起使用 volatile unsigned long rmem_alloc;//接收缓冲队列中存放的数据的大小 /* 下面三个seq用于TCP协议中为保证可靠数据传输而使用的序列号 */ unsigned long write_seq;// unsigned long sent_seq;// unsigned long acked_seq;// unsigned long copied_seq;//应用程序有待读取(但尚未读取)数据的第一个序列号 unsigned long rcv_ack_seq;//目前本地接收到的对本地发送数据的应答序列号 unsigned long window_seq;//窗口大小 unsigned long fin_seq;//应答序列号 //下面两个字段用于紧急数据处理 unsigned long urg_seq;//紧急数据最大序列号 unsigned long urg_data;//标志位,1表示收到紧急数据 /* * Not all are volatile, but some are, so we * might as well say they all are. */ volatile char inuse,//表示其他进程正在使用该sock结构,本进程需等待 dead,//表示该sock结构已处于释放状态 urginline,//=1,表示紧急数据将被当做普通数据处理 intr,// blog, done, reuse, keepopen,//=1,使用保活定时器 linger,//=1,表示在关闭套接字时需要等待一段时间以确认其已关闭 delay_acks,//=1,表示延迟应答 destroy,//=1,表示该sock结构等待销毁 ack_timed, no_check, zapped, /* In ax25 & ipx means not linked */ broadcast, nonagle;//=1,表示不使用NAGLE算法 //NAGLE算法:在前一个发送的数据包被应答之前,不可再继续发送其它数据包 unsigned long lingertime;//等待关闭操作的时间 int proc;//该sock结构所属的进程的进程号 struct sock *next; struct sock *prev; /* Doubly linked chain.. */ struct sock *pair; //下面两个字段用于TCP协议重发队列 struct sk_buff * volatile send_head;//这个队列中的数据均已经发送出去,但尚未接收到应答 struct sk_buff * volatile send_tail; struct sk_buff_head back_log;//接收的数据包缓存队列,当套接字正忙时,数据包暂存在这里 struct sk_buff *partial;//用于创建最大长度的待发送数据包 struct timer_list partial_timer;//定时器,用于按时发送partial指针指向的数据包 long retransmits;//重发次数 struct sk_buff_head write_queue,//指向待发送数据包 receive_queue;//读队列,表示数据报已被正式接收,该队列中的数据可被应用程序读取? struct proto *prot;//传输层处理函数集 struct wait_queue **sleep; unsigned long daddr;//sock结构所代表套接字的远端地址 unsigned long saddr;//本地地址 unsigned short max_unacked;//最大未处理请求连接数 unsigned short window;//远端窗口大小 unsigned short bytes_rcv;//已接收字节总数 /* mss is min(mtu, max_window) */ unsigned short mtu; //和链路层协议密切相关 /* 最大传输单元 */ volatile unsigned short mss; //最大报文长度 =mtu-ip首部长度-tcp首部长度,也就是tcp数据包每次能够传输的最大数据分段 volatile unsigned short user_mss; /* mss requested by user in ioctl */ volatile unsigned short max_window;//最大窗口大小 unsigned long window_clamp;//窗口大小钳制值 unsigned short num;//本地端口号 //下面三个字段用于拥塞算法 volatile unsigned short cong_window; volatile unsigned short cong_count; volatile unsigned short ssthresh; volatile unsigned short packets_out;//本地已发送出去但尚未得到应答的数据包数目 volatile unsigned short shutdown;//本地关闭标志位,用于半关闭操作 volatile unsigned long rtt;//往返时间估计值 volatile unsigned long mdev;//绝对偏差 volatile unsigned long rto;//用rtt和mdev 用算法计算出的延迟时间值 /* currently backoff isn't used, but I'm maintaining it in case * we want to go back to a backoff formula that needs it */ volatile unsigned short backoff;//退避算法度量值 volatile short err;//错误标志值 unsigned char protocol;//传输层协议值 volatile unsigned char state;//套接字状态值 volatile unsigned char ack_backlog;//缓存的未应答数据包个数 unsigned char max_ack_backlog;//最大缓存的未应答数据包个数 unsigned char priority;//该套接字优先级 unsigned char debug; unsigned short rcvbuf;//最大接收缓冲区大小 unsigned short sndbuf;//最大发送缓冲区大小 unsigned short type;//类型值如 SOCK_STREAM unsigned char localroute;//=1,表示只使用本地路由 /* Route locally only */ #ifdef CONFIG_IPX ipx_address ipx_dest_addr; ipx_interface *ipx_intrfc; unsigned short ipx_port; unsigned short ipx_type; #endif #ifdef CONFIG_AX25 /* Really we want to add a per protocol private area */ ax25_address ax25_source_addr,ax25_dest_addr; struct sk_buff *volatile ax25_retxq[8]; char ax25_state,ax25_vs,ax25_vr,ax25_lastrxnr,ax25_lasttxnr; char ax25_condition; char ax25_retxcnt; char ax25_xx; char ax25_retxqi; char ax25_rrtimer; char ax25_timer; unsigned char ax25_n2; unsigned short ax25_t1,ax25_t2,ax25_t3; ax25_digi *ax25_digipeat; #endif #ifdef CONFIG_ATALK struct atalk_sock at; #endif /* IP 'private area' or will be eventually */ int ip_ttl;//ip首部ttl字段值,实际上表示路由器跳数 /* TTL setting */ int ip_tos;//ip首部tos字段值,服务类型值 /* TOS */ struct tcphdr dummy_th;//缓存的tcp首部,在tcp协议中创建一个发送数据包时可以利用此字段快速创建tcp首部 struct timer_list keepalive_timer;//保活定时器,用于探测对方窗口大小,防止对方通报窗口大小的数据包丢弃 /* TCP keepalive hack */ struct timer_list retransmit_timer;//重发定时器,用于数据包超时重发 /* TCP retransmit timer */ struct timer_list ack_timer;//延迟应答定时器 /* TCP delayed ack timer */ int ip_xmit_timeout;//表示定时器超时原因 /* Why the timeout is running */ //用于ip多播 #ifdef CONFIG_IP_MULTICAST int ip_mc_ttl; /* Multicasting TTL */ int ip_mc_loop; /* Loopback (not implemented yet) */ char ip_mc_name[MAX_ADDR_LEN]; /* Multicast device name */ struct ip_mc_socklist *ip_mc_list; /* Group array */ #endif /* This part is used for the timeout functions (timer.c). */ int timeout; /* What are we waiting for? */ struct timer_list timer; /* This is the TIME_WAIT/receive timer when we are doing IP */ struct timeval stamp; /* identd */ //一个套接在在不同的层次上分别由socket结构和sock结构表示 struct socket *socket; /* Callbacks *///回调函数 void (*state_change)(struct sock *sk); void (*data_ready)(struct sock *sk,int bytes); void (*write_space)(struct sock *sk); void (*error_report)(struct sock *sk); };
/* * The DEVICE structure. * Actually, this whole structure is a big mistake. It mixes I/O * data with strictly "high-level" data, and it has to know about * almost every data structure used in the INET module. */ //网络设备结构 struct device { /* * This is the first field of the "visible" part of this structure * (i.e. as seen by users in the "Space.c" file). It is the name * the interface. */ char *name;//设备名称 /* I/O specific fields - FIXME: Merge these and struct ifmap into one */ unsigned long rmem_end;//设备读缓冲区空间 /* shmem "recv" end */ unsigned long rmem_start; /* shmem "recv" start */ unsigned long mem_end;//设备总缓冲区首地址和尾地址 /* sahared mem end */ unsigned long mem_start; /* shared mem start */ unsigned long base_addr;//设备寄存器读写IO基地址 /* device I/O address */ unsigned char irq; //设备所使用中断号 /* device IRQ number */ /* Low-level status flags. */ volatile unsigned char start,//=1,表示设备已处于工作状态 /* start an operation */ tbusy,//=1,表示设备正忙于数据包发送 /* transmitter busy */ interrupt;//=1,软件正在进行设备中断处理 /* interrupt arrived */ struct device *next;//构成设备队列 /* The device initialization function. Called only once. */ int (*init)(struct device *dev);//设备初始化指针(函数指针) /* Some hardware also needs these fields, but they are not part of the usual set specified in Space.c. */ unsigned char if_port;//指定使用的设备端口号 /* Selectable AUI, TP,..*/ unsigned char dma;//设备所用的dma通道号 /* DMA channel */ struct enet_statistics* (*get_stats)(struct device *dev);//设备信息获取函数指针 /* * This marks the end of the "visible" part of the structure. All * fields hereafter are internal to the system, and may change at * will (read: may be cleaned up at will). */ /* These may be needed for future network-power-down code. */ unsigned long trans_start;//用于传输超时计算 /* Time (in jiffies) of last Tx */ unsigned long last_rx;//上次接收一个数据包的时间 /* Time of last Rx */ unsigned short flags;//标志位 /* interface flags (a la BSD) */ unsigned short family;//设备所属的域协议 /* address family ID (AF_INET) */ unsigned short metric; /* routing metric (not used) */ unsigned short mtu;//该接口设备的最大传输单元,ip首部+tcp首部+有效数据负载,去掉了以太网帧的帧头 /* interface MTU value*/ unsigned short type;//该设备所属硬件类型 /* interface hardware type */ unsigned short hard_header_len;//硬件首部长度 /* hardware hdr length */ void *priv;//私有数据指针 /* pointer to private data */ /* Interface address info. */ unsigned char broadcast[MAX_ADDR_LEN];//链路层硬件广播地址 /* hw bcast add */ unsigned char dev_addr[MAX_ADDR_LEN];//本设备硬件地址 /* hw address */ unsigned char addr_len;//硬件地址长度 /* hardware address length */ unsigned long pa_addr;//本地ip地址 /* protocol address */ unsigned long pa_brdaddr;//网络层广播ip地址 /* protocol broadcast addr */ unsigned long pa_dstaddr;//点对点网络中对点的ip地址 /* protocol P-P other side addr */ unsigned long pa_mask;//ip地址网络掩码 /* protocol netmask */ unsigned short pa_alen;//ip地址长度 /* protocol address length */ struct dev_mc_list *mc_list;//多播地址链表 /* Multicast mac addresses */ int mc_count;//多播地址数目 /* Number of installed mcasts */ struct ip_mc_list *ip_mc_list;//网络层ip多播地址链表 /* IP multicast filter chain */ /* For load balancing driver pair support */ unsigned long pkt_queue;//该设备缓存的待发送的数据包个数 /* Packets queued */ struct device *slave;//从设备 /* Slave device */ /* Pointer to the interface buffers. */ struct sk_buff_head buffs[DEV_NUMBUFFS];//设备缓存的待发送的数据包 //函数指针 /* Pointers to interface service routines. */ int (*open)(struct device *dev); int (*stop)(struct device *dev); int (*hard_start_xmit) (struct sk_buff *skb, struct device *dev); int (*hard_header) (unsigned char *buff, struct device *dev, unsigned short type, void *daddr, void *saddr, unsigned len, struct sk_buff *skb); int (*rebuild_header)(void *eth, struct device *dev, unsigned long raddr, struct sk_buff *skb); //用于从接收到的数据包提取MAC首部中类型字符值,从而将数据包传送给适当的协议处理函数进行处理 unsigned short (*type_trans) (struct sk_buff *skb, struct device *dev); #define HAVE_MULTICAST void (*set_multicast_list)(struct device *dev, int num_addrs, void *addrs); #define HAVE_SET_MAC_ADDR int (*set_mac_address)(struct device *dev, void *addr); #define HAVE_PRIVATE_IOCTL int (*do_ioctl)(struct device *dev, struct ifreq *ifr, int cmd); #define HAVE_SET_CONFIG int (*set_config)(struct device *dev, struct ifmap *map); };
/* This is an Ethernet frame header. */ struct ethhdr { unsigned char h_dest[ETH_ALEN];//目的地址 /* destination eth addr */ unsigned char h_source[ETH_ALEN];//源地址 /* source ether addr */ unsigned short h_proto;//类型 /* packet type ID field */ };