网络编程培训之一 编程实现IP/TCP/UDP报文

系列博客参考:http://blog.csdn.net/zy416548283/article/category/1108400
代码以编号对应放在Github上:https://github.com/zy416548283/networkProgramming

题目

编程实现 IP,TCP,UDP 报文格式。实现报文添加头部、取出
头部等基本操作。

题目解读

  • 我们在很多讲解TCP/IP的书上都可以看到TCP/UDP/IP的结构定义格式,以及每个字段的作用,不太清楚的可以参考博客:http://blog.chinaunix.net/uid-26833883-id-3627644.html 下文的源码也都可以结合着报文格式来阅读。
  • 关于怎么定义报文格式,我们使用我们熟悉的编程语言都可以很容易的去定义。我们知道linux是开源的,我们可以来看看linux中是怎么定义这些报文的。在阅读源码中,经常会用到跳转查看代码的定义,这里采用的是vim+ctags,方便快捷。
  • 写作中,参考了博客:http://blog.csdn.net/l1902090/article/details/25913351 
  • 从上可以知道关键字是:TCP/UDP/IP报文 linux 数据结构 位操作

题目实现

ip报文头

ipheader是在/usr/include/linux/ip.h中定义的:

struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8    ihl:4,
        version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
    __u8    version:4,
        ihl:4;
#else
#error  "Please fix <asm/byteorder.h>"
#endif
    __u8    tos;
    __be16  tot_len;
    __be16  id;
    __be16  frag_off;
    __u8    ttl;
    __u8    protocol;
    __sum16 check;
    __be32  saddr;
    __be32  daddr;
    /*The options start here. */
};
  • 源码里使用了自己定义的数据类型,比如__u8等,这个在驱动编写里经常会用到,可以让你一看名字就知道所占内存的大小,具体可以看看知乎上的解答:http://www.zhihu.com/question/23223900 关于__be16,最开始以为是bigEndian,怎么都无法理解,查看代码就知道是:typedef __u16 __bitwise __be16; 关于bitwise,它能够提供超强制的类型匹配检查,可以参考:http://www.lenky.info/archives/2012/07/1776
  • 有了上面的定义,就会想怎么使用呢?  一般我们拿到的是一个字符数组的数据,强制赋给一个iphdr的指针就可以了,然后就可以解析IP报文头部了。如下:
IP *ip;UDP *udp;TCP *tcp;
ip=(IP *)buff1;udp=(UDP *)(buff1+20);tcp=(TCP *)(buff2+20);

UDP报文头

udp的报文头定义是在/usr/include/linux/udp.h中

struct udphdr {
    __be16  source;
    __be16  dest;
    __be16  len;
    __sum16 check;
};

分析和使用和前面的IP报文头一样。

TCP报文头

struct tcphdr {
    __be16  source;
    __be16  dest;
    __be32  seq;
    __be32  ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u16   res1:4,
        doff:4,
        fin:1,
        syn:1,
        rst:1,
        psh:1,
        ack:1,
        urg:1,
        ece:1,
        cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
    __u16   doff:4,
        res1:4,
        cwr:1,
        ece:1,
        urg:1,
        ack:1,
        psh:1,
        rst:1,
        syn:1,
        fin:1;
#else
#error  "Adjust your <asm/byteorder.h> defines"
#endif  
    __be16  window;
    __sum16 check;
    __be16  urg_ptr;
};
  • 在解析IP报文头的时候,可以获取到传输层使用的是什么协议,然后再按照对应的传输层的报文去解析就ok.

题目思考与扩展

  • 阅读优秀的源码,可以学会思考别人考虑的东西;
  • 学会了解析报文,在应用层自己定义和解析报文非常的有用,并且可以自己去尝试写一个报文解析工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值