zoukankan      html  css  js  c++  java
  • 【Linux 内核网络协议栈源码剖析】网络栈主要结构介绍(socket、sock、sk_buff,etc)


    http://blog.csdn.net/wenqian1991/article/details/46700177


    通过前面的分析,可以发现,网络协议栈中的数据处理,都是基于各类结构体,所有有关于网络栈中数据包的状态,地址,端口等信息都封装在对应的结构中,可以说,了解这些数据结构是理解网络栈源码的基础,这里我们就来了解下网络协议栈中的各类数据结构。Linux 1.2.13

    1、socket

    (includelinuxSocket.h)该结构体socket 主要使用在BSD socket 层,是最上层的结构,在INET socket 层也会有涉及,但很少。

    1. /* 
    2.  * Internal representation of a socket. not all the fields are used by 
    3.  * all configurations: 
    4.  * 
    5.  *            server                client 
    6.  * conn     client connected to server connected to 
    7.  * iconn        list of clients     -unused- 
    8.  *       awaiting connections 
    9.  * wait     sleep for clients,  sleep for connection, 
    10.  *          sleep for i/o               sleep for i/o 
    11.  */  
    12.  //该结构表示一个网络套接字  
    13. struct socket {  
    14.   short         type;       /* 套接字所用的流类型*/  
    15.   socket_state      state;//套接字所处状态  
    16.   long          flags;//标识字段,目前尚无明确作用  
    17.   struct proto_ops  *ops;       /* 操作函数集指针  */  
    18.     /* data保存指向‘私有'数据结构指针,在不同的域指向不同的数据结构        */  
    19.   //在INET域,指向sock结构,UNIX域指向unix_proto_data结构  
    20.   void          *data;    
    21.   //下面两个字段只用于UNIX域  
    22.   struct socket     *conn;      /* 指向连接的对端套接字   */  
    23.   struct socket     *iconn;     /* 指向正等待连接的客户端(服务器端)    */  
    24.   struct socket     *next;//链表  
    25.   struct wait_queue **wait;     /* 等待队列 */  
    26.   struct inode      *inode;//inode结构指针  
    27.   struct fasync_struct  *fasync_list;   /* 异步唤醒链表结构 */  
    28. };  

    2、sock

    (includelinuxNet.h) sock 的使用范围比socket 要大得多,sock结构的使用基本贯穿硬件层、设备接口层、ip层、INET socket 层,而且是作为各层之间的一个联系,主要是因为无论是发送还是接收的数据包都要被缓存到sock 结构中的缓冲队列中。

    sock 结构与其对应的 socket 会相互绑定。 

    1. /* 
    2.  * This structure really needs to be cleaned up. 
    3.  * Most of it is for TCP, and not used by any of 
    4.  * the other protocols. 
    5.  * 大部分功能是为TCP准备的 
    6.  */  
    7. struct sock {  
    8.   struct options        *opt;//IP选项缓冲于此处  
    9.   volatile unsigned long    wmem_alloc;//发送缓冲队列中存放的数据的大小,这两个与后面的rcvbuf和sndbuf一起使用  
    10.   volatile unsigned long    rmem_alloc;//接收缓冲队列中存放的数据的大小  
    11.   /* 下面三个seq用于TCP协议中为保证可靠数据传输而使用的序列号 */  
    12.   unsigned long         write_seq;//  
    13.   unsigned long         sent_seq;//  
    14.   unsigned long         acked_seq;//  
    15.   unsigned long         copied_seq;//应用程序有待读取(但尚未读取)数据的第一个序列号  
    16.   unsigned long         rcv_ack_seq;//目前本地接收到的对本地发送数据的应答序列号  
    17.   unsigned long         window_seq;//窗口大小  
    18.   unsigned long         fin_seq;//应答序列号  
    19.   //下面两个字段用于紧急数据处理  
    20.   unsigned long         urg_seq;//紧急数据最大序列号  
    21.   unsigned long         urg_data;//标志位,1表示收到紧急数据  
    22.   
    23.   /* 
    24.    * Not all are volatile, but some are, so we 
    25.    * might as well say they all are. 
    26.    */  
    27.   volatile char                 inuse,//表示其他进程正在使用该sock结构,本进程需等待  
    28.                 dead,//表示该sock结构已处于释放状态  
    29.                 urginline,//=1,表示紧急数据将被当做普通数据处理  
    30.                 intr,//  
    31.                 blog,  
    32.                 done,  
    33.                 reuse,  
    34.                 keepopen,//=1,使用保活定时器  
    35.                 linger,//=1,表示在关闭套接字时需要等待一段时间以确认其已关闭  
    36.                 delay_acks,//=1,表示延迟应答  
    37.                 destroy,//=1,表示该sock结构等待销毁  
    38.                 ack_timed,  
    39.                 no_check,  
    40.                 zapped, /* In ax25 & ipx means not linked */  
    41.                 broadcast,  
    42.                 nonagle;//=1,表示不使用NAGLE算法  
    43.                 //NAGLE算法:在前一个发送的数据包被应答之前,不可再继续发送其它数据包  
    44.   unsigned long             lingertime;//等待关闭操作的时间  
    45.   int               proc;//该sock结构所属的进程的进程号  
    46.   struct sock           *next;  
    47.   struct sock           *prev; /* Doubly linked chain.. */  
    48.   struct sock           *pair;  
    49.   //下面两个字段用于TCP协议重发队列  
    50.   struct sk_buff        * volatile send_head;//这个队列中的数据均已经发送出去,但尚未接收到应答  
    51.   struct sk_buff        * volatile send_tail;  
    52.   struct sk_buff_head       back_log;//接收的数据包缓存队列,当套接字正忙时,数据包暂存在这里  
    53.   struct sk_buff        *partial;//用于创建最大长度的待发送数据包  
    54.   struct timer_list     partial_timer;//定时器,用于按时发送partial指针指向的数据包  
    55.   long              retransmits;//重发次数  
    56.   struct sk_buff_head       write_queue,//指向待发送数据包  
    57.                 receive_queue;//读队列,表示数据报已被正式接收,该队列中的数据可被应用程序读取?  
    58.   struct proto          *prot;//传输层处理函数集  
    59.   struct wait_queue     **sleep;  
    60.   unsigned long         daddr;//sock结构所代表套接字的远端地址  
    61.   unsigned long         saddr;//本地地址  
    62.   unsigned short        max_unacked;//最大未处理请求连接数  
    63.   unsigned short        window;//远端窗口大小  
    64.   unsigned short        bytes_rcv;//已接收字节总数  
    65. /* mss is min(mtu, max_window) */  
    66.   unsigned short        mtu; //和链路层协议密切相关      /* 最大传输单元 */  
    67.   volatile unsigned short   mss; //最大报文长度 =mtu-ip首部长度-tcp首部长度,也就是tcp数据包每次能够传输的最大数据分段  
    68.   volatile unsigned short   user_mss;  /* mss requested by user in ioctl */  
    69.   volatile unsigned short   max_window;//最大窗口大小  
    70.   unsigned long         window_clamp;//窗口大小钳制值  
    71.   unsigned short        num;//本地端口号  
    72.   //下面三个字段用于拥塞算法  
    73.   volatile unsigned short   cong_window;  
    74.   volatile unsigned short   cong_count;  
    75.   volatile unsigned short   ssthresh;  
    76.   volatile unsigned short   packets_out;//本地已发送出去但尚未得到应答的数据包数目  
    77.   volatile unsigned short   shutdown;//本地关闭标志位,用于半关闭操作  
    78.   volatile unsigned long    rtt;//往返时间估计值  
    79.   volatile unsigned long    mdev;//绝对偏差  
    80.   volatile unsigned long    rto;//用rtt和mdev 用算法计算出的延迟时间值  
    81. /* currently backoff isn't used, but I'm maintaining it in case 
    82.  * we want to go back to a backoff formula that needs it 
    83.  */  
    84.   volatile unsigned short   backoff;//退避算法度量值  
    85.   volatile short        err;//错误标志值  
    86.   unsigned char         protocol;//传输层协议值  
    87.   volatile unsigned char    state;//套接字状态值  
    88.   volatile unsigned char    ack_backlog;//缓存的未应答数据包个数  
    89.   unsigned char         max_ack_backlog;//最大缓存的未应答数据包个数  
    90.   unsigned char         priority;//该套接字优先级  
    91.   unsigned char         debug;  
    92.   unsigned short        rcvbuf;//最大接收缓冲区大小  
    93.   unsigned short        sndbuf;//最大发送缓冲区大小  
    94.   unsigned short        type;//类型值如 SOCK_STREAM  
    95.   unsigned char         localroute;//=1,表示只使用本地路由 /* Route locally only */  
    96. #ifdef CONFIG_IPX  
    97.   ipx_address           ipx_dest_addr;  
    98.   ipx_interface         *ipx_intrfc;  
    99.   unsigned short        ipx_port;  
    100.   unsigned short        ipx_type;  
    101. #endif  
    102. #ifdef CONFIG_AX25  
    103. /* Really we want to add a per protocol private area */  
    104.   ax25_address          ax25_source_addr,ax25_dest_addr;  
    105.   struct sk_buff *volatile  ax25_retxq[8];  
    106.   char              ax25_state,ax25_vs,ax25_vr,ax25_lastrxnr,ax25_lasttxnr;  
    107.   char              ax25_condition;  
    108.   char              ax25_retxcnt;  
    109.   char              ax25_xx;  
    110.   char              ax25_retxqi;  
    111.   char              ax25_rrtimer;  
    112.   char              ax25_timer;  
    113.   unsigned char         ax25_n2;  
    114.   unsigned short        ax25_t1,ax25_t2,ax25_t3;  
    115.   ax25_digi         *ax25_digipeat;  
    116. #endif    
    117. #ifdef CONFIG_ATALK  
    118.   struct atalk_sock     at;  
    119. #endif  
    120.   
    121. /* IP 'private area' or will be eventually */  
    122.   int               ip_ttl;//ip首部ttl字段值,实际上表示路由器跳数      /* TTL setting */  
    123.   int               ip_tos;//ip首部tos字段值,服务类型值       /* TOS */  
    124.   struct tcphdr         dummy_th;//缓存的tcp首部,在tcp协议中创建一个发送数据包时可以利用此字段快速创建tcp首部  
    125.   struct timer_list     keepalive_timer;//保活定时器,用于探测对方窗口大小,防止对方通报窗口大小的数据包丢弃 /* TCP keepalive hack */  
    126.   struct timer_list     retransmit_timer;//重发定时器,用于数据包超时重发  /* TCP retransmit timer */  
    127.   struct timer_list     ack_timer;//延迟应答定时器     /* TCP delayed ack timer */  
    128.   int               ip_xmit_timeout;//表示定时器超时原因 /* Why the timeout is running */  
    129.   
    130. //用于ip多播  
    131. #ifdef CONFIG_IP_MULTICAST    
    132.   int               ip_mc_ttl;          /* Multicasting TTL */  
    133.   int               ip_mc_loop;         /* Loopback (not implemented yet) */  
    134.   char              ip_mc_name[MAX_ADDR_LEN];   /* Multicast device name */  
    135.   struct ip_mc_socklist     *ip_mc_list;            /* Group array */  
    136. #endif    
    137.   
    138.   /* This part is used for the timeout functions (timer.c). */  
    139.   int               timeout;    /* What are we waiting for? */  
    140.   struct timer_list     timer;      /* This is the TIME_WAIT/receive timer when we are doing IP */  
    141.   struct timeval        stamp;  
    142.   
    143.   /* identd */  
    144.   //一个套接在在不同的层次上分别由socket结构和sock结构表示  
    145.   struct socket         *socket;  
    146.     
    147.   /* Callbacks *///回调函数  
    148.   void              (*state_change)(struct sock *sk);  
    149.   void              (*data_ready)(struct sock *sk,int bytes);  
    150.   void              (*write_space)(struct sock *sk);  
    151.   void              (*error_report)(struct sock *sk);  
    152.     
    153. };  
    3、sk_buff

    (includelinuxSkbuff.h) sk_buff 是网络数据报在内核中的表现形式,通过源码可以看出,数据包在内核协议栈中是通过这个数据结构来变现的。

    从其中的 union 字段可以看出,该结构是贯穿在各个层的,可以说这个结构是用来为网络数据包服务的。其中的字段表明了数据包隶属的套接字、当前所处的协议层、所搭载的数据负载长度(data指针指向)、源端,目的端地址以及相关字段等。

    主要重要的一个字段是 data[0],这是一个指针,它指向对应层的数据报(首部+数据负载)内容的首地址。怎么解释呢?

    如果在传输层,那么data指向的数据部分的首地址,其数据部分为 TCP 首部 + 有效数据负载。

    如果在网络层,data指向的数据部分的首地址,其数据部分为 IP 首部 + TCP 首部 + 有效数据负载。

    如果在链路层,data指向的首地址,其数据布局为 MAC 首部 + IP 首部 + TCP 首部 + 有效数据负载。

    所以在该skb_buff结构传递时,获取某一层的首部,都是通过拷贝 data 指向地址对应首部大小的数据。

    1.   //sk_buff 结构用来封装网络数据  
    2.   //网络栈代码对数据的处理都是以sk_buff 结构为单元进行的  
    3. struct sk_buff {  
    4.   struct sk_buff        * volatile next;  
    5.   struct sk_buff        * volatile prev;//构成队列  
    6. #if CONFIG_SKB_CHECK  
    7.   int               magic_debug_cookie; //调试用  
    8. #endif  
    9.   struct sk_buff        * volatile link3; //构成数据包重发队列  
    10.   struct sock           *sk; //数据包所属的套接字  
    11.   volatile unsigned long    when;    //数据包的发送时间,用于计算往返时间RTT/* used to compute rtt's */  
    12.   struct timeval        stamp; //记录时间  
    13.   struct device         *dev; //接收该数据包的接口设备  
    14.   struct sk_buff        *mem_addr; //该sk_buff在内存中的基地址,用于释放该sk_buff结构  
    15.   //联合类型,表示数据报在不同处理层次上所到达的处理位置  
    16.   union {  
    17.     struct tcphdr   *th; //传输层tcp,指向首部第一个字节位置  
    18.     struct ethhdr   *eth; //链路层上,指向以太网首部第一个字节位置  
    19.     struct iphdr    *iph; //网络层上,指向ip首部第一个字节位置  
    20.     struct udphdr   *uh; //传输层udp协议,  
    21.     unsigned char   *raw; //随层次变化而变化,链路层=eth,网络层=iph  
    22.     unsigned long   seq; //针对tcp协议的待发送数据包而言,表示该数据包的ACK值  
    23.   } h;  
    24.   struct iphdr      *ip_hdr; //指向ip首部的指针        /* For IPPROTO_RAW */  
    25.   unsigned long         mem_len; //表示sk_buff结构大小加上数据部分的总长度  
    26.   unsigned long         len; //只表示数据部分长度,len = mem_len - sizeof(sk_buff)  
    27.   unsigned long         fraglen; //分片数据包个数  
    28.   struct sk_buff        *fraglist;  /* Fragment list */  
    29.   unsigned long         truesize; //同men_len  
    30.   unsigned long         saddr; //源端ip地址  
    31.   unsigned long         daddr; //目的端ip地址  
    32.   unsigned long         raddr; //数据包下一站ip地址     /* next hop addr */  
    33.    //标识字段  
    34.   volatile char         acked, //=1,表示数据报已得到确认,可以从重发队列中删除  
    35.                 used, //=1,表示该数据包的数据已被应用程序读完,可以进行释放  
    36.                 free, //用于数据包发送,=1表示再进行发送操作后立即释放,无需缓存  
    37.                 arp; //用于待发送数据包,=1表示已完成MAC首部的建立,=0表示还不知道目的端MAC地址  
    38.   //已进行tries试发送,该数据包正在被其余部分使用,路由类型,数据包类型  
    39.   unsigned char         tries,lock,localroute,pkt_type;  
    40.    //下面是数据包的类型,即pkt_type的取值  
    41. #define PACKET_HOST     0     //发往本机    /* To us */  
    42. #define PACKET_BROADCAST    1 //广播  
    43. #define PACKET_MULTICAST    2 //多播  
    44. #define PACKET_OTHERHOST    3 //其他机器        /* Unmatched promiscuous */  
    45.   unsigned short        users; //使用该数据包的模块数     /* User count - see datagram.c (and soon seqpacket.c/stream.c) */  
    46.   unsigned short        pkt_class;  /* For drivers that need to cache the packet type with the skbuff (new PPP) */  
    47. #ifdef CONFIG_SLAVE_BALANCING  
    48.   unsigned short        in_dev_queue; //该字段是否正在缓存于设备缓存队列中  
    49. #endif    
    50.   unsigned long         padding[0]; //填充字节  
    51.   unsigned char         data[0]; //指向该层数据部分  
    52.   //data指向的数据负载首地址,在各个层对应不同的数据部分  
    53. //从侧面看出sk_buff结构基本上是贯穿整个网络栈的非常重要的一个数据结构  
    54. };  

    4、device

    (includelinuxNetdevice.h)该结构表明了一个网络设备需要的字段信息。

    1. /* 
    2.  * The DEVICE structure. 
    3.  * Actually, this whole structure is a big mistake.  It mixes I/O 
    4.  * data with strictly "high-level" data, and it has to know about 
    5.  * almost every data structure used in the INET module.   
    6.  */  
    7.   //网络设备结构  
    8. struct device   
    9. {  
    10.   
    11.   /* 
    12.    * This is the first field of the "visible" part of this structure 
    13.    * (i.e. as seen by users in the "Space.c" file).  It is the name 
    14.    * the interface. 
    15.    */  
    16.   char            *name;//设备名称  
    17.   
    18.   /* I/O specific fields - FIXME: Merge these and struct ifmap into one */  
    19.   unsigned long       rmem_end;//设备读缓冲区空间       /* shmem "recv" end */  
    20.   unsigned long       rmem_start;       /* shmem "recv" start   */  
    21.   unsigned long       mem_end;//设备总缓冲区首地址和尾地址       /* sahared mem end  */  
    22.   unsigned long       mem_start;        /* shared mem start */  
    23.   unsigned long       base_addr;//设备寄存器读写IO基地址      /* device I/O address   */  
    24.   unsigned char       irq;  //设备所使用中断号      /* device IRQ number    */  
    25.   
    26.   /* Low-level status flags. */  
    27.   volatile unsigned char  start,//=1,表示设备已处于工作状态        /* start an operation   */  
    28.                           tbusy,//=1,表示设备正忙于数据包发送       /* transmitter busy */  
    29.                           interrupt;//=1,软件正在进行设备中断处理       /* interrupt arrived    */  
    30.   
    31.   struct device       *next;//构成设备队列  
    32.   
    33.   /* The device initialization function. Called only once. */  
    34.   int             (*init)(struct device *dev);//设备初始化指针(函数指针)  
    35.   
    36.   /* Some hardware also needs these fields, but they are not part of the 
    37.      usual set specified in Space.c. */  
    38.   unsigned char       if_port;//指定使用的设备端口号      /* Selectable AUI, TP,..*/  
    39.   unsigned char       dma;//设备所用的dma通道号         /* DMA channel      */  
    40.   
    41.   struct enet_statistics* (*get_stats)(struct device *dev);//设备信息获取函数指针  
    42.   
    43.   /* 
    44.    * This marks the end of the "visible" part of the structure. All 
    45.    * fields hereafter are internal to the system, and may change at 
    46.    * will (read: may be cleaned up at will). 
    47.    */  
    48.   
    49.   /* These may be needed for future network-power-down code. */  
    50.   unsigned long       trans_start;//用于传输超时计算    /* Time (in jiffies) of last Tx */  
    51.   unsigned long       last_rx;//上次接收一个数据包的时间    /* Time of last Rx      */  
    52.   
    53.   unsigned short      flags;//标志位   /* interface flags (a la BSD)   */  
    54.   unsigned short      family;//设备所属的域协议 /* address family ID (AF_INET)  */  
    55.   unsigned short      metric;   /* routing metric (not used)    */  
    56.   unsigned short      mtu;//该接口设备的最大传输单元,ip首部+tcp首部+有效数据负载,去掉了以太网帧的帧头 /* interface MTU value*/  
    57.   unsigned short      type;//该设备所属硬件类型      /* interface hardware type  */  
    58.   unsigned short      hard_header_len;//硬件首部长度  /* hardware hdr length  */  
    59.   void            *priv;//私有数据指针    /* pointer to private data  */  
    60.   
    61.   /* Interface address info. */  
    62.   unsigned char       broadcast[MAX_ADDR_LEN];//链路层硬件广播地址   /* hw bcast add */  
    63.   unsigned char       dev_addr[MAX_ADDR_LEN];//本设备硬件地址  /* hw address   */  
    64.   unsigned char       addr_len;//硬件地址长度 /* hardware address length  */  
    65.   unsigned long       pa_addr;//本地ip地址  /* protocol address     */  
    66.   unsigned long       pa_brdaddr;//网络层广播ip地址    /* protocol broadcast addr  */  
    67.   unsigned long       pa_dstaddr;//点对点网络中对点的ip地址    /* protocol P-P other side addr */  
    68.   unsigned long       pa_mask;//ip地址网络掩码    /* protocol netmask     */  
    69.   unsigned short      pa_alen;//ip地址长度  /* protocol address length  */  
    70.   
    71.   struct dev_mc_list     *mc_list;//多播地址链表  /* Multicast mac addresses  */  
    72.   int            mc_count;//多播地址数目  /* Number of installed mcasts   */  
    73.     
    74.   struct ip_mc_list  *ip_mc_list;//网络层ip多播地址链表  /* IP multicast filter chain    */  
    75.       
    76.   /* For load balancing driver pair support */  
    77.     
    78.   unsigned long        pkt_queue;//该设备缓存的待发送的数据包个数  /* Packets queued */  
    79.   struct device       *slave;//从设备  /* Slave device */  
    80.     
    81.   
    82.   /* Pointer to the interface buffers. */  
    83.   struct sk_buff_head     buffs[DEV_NUMBUFFS];//设备缓存的待发送的数据包  
    84.   
    85.  //函数指针  
    86.   /* Pointers to interface service routines. */  
    87.   int             (*open)(struct device *dev);  
    88.   int             (*stop)(struct device *dev);  
    89.   int             (*hard_start_xmit) (struct sk_buff *skb,  
    90.                           struct device *dev);  
    91.   int             (*hard_header) (unsigned char *buff,  
    92.                       struct device *dev,  
    93.                       unsigned short type,  
    94.                       void *daddr,  
    95.                       void *saddr,  
    96.                       unsigned len,  
    97.                       struct sk_buff *skb);  
    98.   int             (*rebuild_header)(void *eth, struct device *dev,  
    99.                 unsigned long raddr, struct sk_buff *skb);  
    100.   
    101.   //用于从接收到的数据包提取MAC首部中类型字符值,从而将数据包传送给适当的协议处理函数进行处理  
    102.   unsigned short      (*type_trans) (struct sk_buff *skb,  
    103.                      struct device *dev);  
    104. #define HAVE_MULTICAST             
    105.   void            (*set_multicast_list)(struct device *dev,  
    106.                      int num_addrs, void *addrs);  
    107. #define HAVE_SET_MAC_ADDR          
    108.   int             (*set_mac_address)(struct device *dev, void *addr);  
    109. #define HAVE_PRIVATE_IOCTL  
    110.   int             (*do_ioctl)(struct device *dev, struct ifreq *ifr, int cmd);  
    111. #define HAVE_SET_CONFIG  
    112.   int             (*set_config)(struct device *dev, struct ifmap *map);  
    113.     
    114. };  

    5、tcp 首部格式

    1.  //tcp首部格式  
    2.  //http://blog.csdn.net/wenqian1991/article/details/44598537  
    3. struct tcphdr {  
    4.     __u16   source;//源端口号  
    5.     __u16   dest;//目的端口号  
    6.     __u32   seq;//32位序列号  
    7.     __u32   ack_seq;//32位确认号  
    8. #if defined(LITTLE_ENDIAN_BITFIELD)  
    9.     __u16   res1:4,//4位首部长度  
    10.         doff:4,//保留  
    11.         //下面为各个控制位  
    12.         fin:1,//最后控制位,表示数据已全部传输完成  
    13.         syn:1,//同步控制位  
    14.         rst:1,//重置控制位  
    15.         psh:1,//推控制位  
    16.         ack:1,//确认控制位  
    17.         urg:1,//紧急控制位  
    18.         res2:2;//  
    19. #elif defined(BIG_ENDIAN_BITFIELD)  
    20.     __u16   doff:4,  
    21.         res1:4,  
    22.         res2:2,  
    23.         urg:1,  
    24.         ack:1,  
    25.         psh:1,  
    26.         rst:1,  
    27.         syn:1,  
    28.         fin:1;  
    29. #else  
    30. #error  "Adjust your <asm/byteorder.h> defines"  
    31. #endif    
    32.     __u16   window;//16位窗口大小  
    33.     __u16   check;//16位校验和  
    34.     __u16   urg_ptr;//16位紧急指针  
    35. };  
    6、ip 首部格式
    1.  //ip数据报,首部格式  
    2. struct iphdr {  
    3. #if defined(LITTLE_ENDIAN_BITFIELD)//如果是小端模式  
    4.     __u8    ihl:4,//首部长度  
    5.         version:4;//版本  
    6. #elif defined (BIG_ENDIAN_BITFIELD)//大端  
    7.     __u8    version:4,  
    8.         ihl:4;  
    9. #else  
    10. #error  "Please fix <asm/byteorder.h>"  
    11. #endif  
    12.     __u8    tos;//区分服务,用语表示数据报的优先级和服务类型  
    13.     __u16   tot_len;//总长度,标识整个ip数据报的总长度 = 报头+数据部分  
    14.     __u16   id;//表示ip数据报的标识符  
    15.     __u16   frag_off;//片偏移  
    16.     __u8    ttl;//生存时间,即ip数据报在网络中传输的有效期  
    17.     __u8    protocol;//协议,标识此ip数据报在传输层所采用的协议类型  
    18.     __u16   check;//首部校验和  
    19.     __u32   saddr;//源地址  
    20.     __u32   daddr;//目的地址  
    21.     /*The options start here. */  
    22. };  
    7、以太网帧帧头格式
    1. /* This is an Ethernet frame header. */  
    2. struct ethhdr {  
    3.   unsigned char     h_dest[ETH_ALEN];//目的地址 /* destination eth addr */  
    4.   unsigned char     h_source[ETH_ALEN];//源地址    /* source ether addr    */  
    5.   unsigned short    h_proto;//类型        /* packet type ID field */  
    6. };  

    8、ARP报文报头

    1. /* 
    2.  *  This structure defines an ethernet arp header. 
    3.  */  
    4.  //ARP报文格式(arp报头)  
    5. struct arphdr  
    6. {  
    7.     unsigned short  ar_hrd;//硬件类型       /* format of hardware address   */  
    8.     unsigned short  ar_pro;//上层协议类型     /* format of protocol address   */  
    9.     unsigned char   ar_hln;//MAC地址长度        /* length of hardware address   */  
    10.     unsigned char   ar_pln;//协议地址长度     /* length of protocol address   */  
    11.     unsigned short  ar_op;//操作类型        /* ARP opcode (command)     */  
    12.   
    13. #if 0  
    14.      /* 
    15.       *  Ethernet looks like this : This bit is variable sized however... 
    16.       */  
    17.     unsigned char       ar_sha[ETH_ALEN];//源MAC地址   /* sender hardware address  */  
    18.     unsigned char       ar_sip[4];//源IP地址       /* sender IP address        */  
    19.     unsigned char       ar_tha[ETH_ALEN];//目的MAC地址  /* target hardware address  */  
    20.     unsigned char       ar_tip[4];//目的IP地址      /* target IP address        */  
    21. #endif  
    22.   
    23. };  


  • 相关阅读:
    使用 Python 编码和解码 JSON 对象
    搞定github下载加速
    git错误:fatal: Could not read from remote repository.解决
    webstorm安装配置
    node.js下载安装
    IDEA安装小配置
    JAVA软件安装
    关于升级一般软件的一些想法
    linux 的 逻辑卷管理
    记一次内核升级。
  • 原文地址:https://www.cnblogs.com/ztguang/p/12645505.html
Copyright © 2011-2022 走看看