tcp/ip协议学习 第三章 IP协议

派猴子来的救兵

关于IP的RFC文档在此!

IP的头文件还是先贴一下, 总是记不住.

   0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version|  IHL  |Type of Service|          Total Length         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |Flags|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Time to Live |    Protocol   |         Header Checksum       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Source Address                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Destination Address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

网络和子网划分

不太明白ABCD四类地址划分的意义,除了在路由选择的匹配中会配合子网划分用到.

路由表, 路由选择

以前本科的时候, IP配置好之后, 学校内网是可以访问的. 如果想访问外网, 需要拨号.但拨号之后内网就不方便上了.

学校网站有个小程序, 可以傻瓜式的修改系统路由. 拨号之后内网外网一起上.

当时不明白这是个什么东西, 其实现在也想不太明白怎么回事, 也没条件回学校试验下了. 但至少现在也算大概明白路由表以及路由选择了.

之前为了学习, 拿公司的网络实验了一把. osx下面的双网卡路由配置

来段程序吧

python

用程序发送raw IP包的时候, Total Length 和 Checksum 会由内核自动生成. 至于为啥,可能看到tcpip协议详解下(实现)的时候就知道了吧.

Checksum 算法在模拟后面协议的时候就要自己实现了.ICMP、IGMP、UDP和TCP都采用相同的检验和算法.

有个不同点是: 首部检验和字段是根据IP头计算的检验和码。它不对body进行计算。 ICMP、 IGMP、UDP和TCP的checksum覆盖首部和数据。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

‘‘‘发送一个裸的IP包, 20字节的IP头, 后面跟一个随便写的字符串.
还不知道IP包的ID应该根据什么生成, 就随便写了一个54321
IP头里面:
    IP包总长度属性和checksum属性都是内核自动生成的.
    协议是用的socket.IPPROTO_TCP,也就是6.但没什么用,IP包里面就随便的字符串,不是按TCP协议来的.
‘‘‘

import socket
from struct import pack
import sys

def main():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
    except socket.error as msg:
        print ‘Socket could not be created. Error Code : ‘ + str(msg[0]) + ‘ Message ‘ + msg[1]
        return

    packet = ‘‘

    source_ip = ‘127.0.0.1‘
    dest_ip = ‘127.0.0.1‘

    # ip header fields
    ip_ver = 4
    ip_ihl = 5
    ip_tos = 0
    ip_tot_len = 0  # kernel will fill the correct total length
    ip_id = 54321
    ip_frag_off = 0
    ip_ttl = 32
    ip_proto = socket.IPPROTO_TCP  # no use in this case
    ip_checksum = 0    # kernel will fill the correct checksum

    ip_saddr = socket.inet_aton(source_ip)
    ip_daddr = socket.inet_aton(dest_ip)

    ip_ihl_ver = (ip_ver << 4) + ip_ihl

    # the ! in the pack format string means network order
    ip_header = pack(
        ‘!BBHHHBBH4s4s‘,
        ip_ihl_ver,
        ip_tos,
        ip_tot_len,
        ip_id,
        ip_frag_off,
        ip_ttl,
        ip_proto,
        ip_checksum,
        ip_saddr,
        ip_daddr)

    user_data = sys.argv[1] if sys.argv[1:] else ‘0123456789‘

    packet = ip_header + user_data

    # the port specified has no effect
    r = s.sendto(packet, (dest_ip, 0))

    # result is the length of packet sent out
    print r

if __name__ == ‘__main__‘:
    main()
    ip_check = 1231    # kernel will fill the correct checksum

抓包. 运行环境, ubuntu12.04

% sudo tcpdump -i lo -x -vvv -t -c 1                                                                                                ?
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
IP (tos 0x0, ttl 32, id 54321, offset 0, flags [none], proto TCP (6), length 30)
    localhost.12337 > localhost.12851:  tcp 10 [bad hdr length 0 - too short, < 20]
    0x0000:  4500 001e d431 0000 2006 c8a6 7f00 0001
    0x0010:  7f00 0001 3031 3233 3435 3637 3839
1 packet captured
2 packets received by filter
0 packets dropped by kernel

tcp 10 [bad hdr length 0 - too short, < 20] 是说IP body里面的字节数太少, 只有10, 小于TCP header应有的20字节.

  • 1字节, 45, 4代表Version, 5代表Header Length, 单位是4Byte.
  • 2字节, 00, OTS(Type of Service), 代表此IP包的最小时延,最大吞吐量,最高可靠性, 最小费用等特征. 比如用于FTP的控制的IP包, 应该是最小时延, 用于FTP的数据的IP包, 则应该是最大吞吐量.书中提到:

    现在大多数的TCP/IP实现都不支持TOS特性,但是自4.3BSD Reno以后的新版系统都对它

    进行了设置。另外,新的路由协议如 OSPF和IS-IS都能根据这些字段的值进行路由决策。

  • 3,4字节, 001e, Total Length. 0x1e = 30; 发送的01234567890+20字节的IP Header.
    因为一些数据链路(如以太网)需要填充一些数据以达到最小长度。尽管以太网的最小帧长为 46字节,但是IP数据可能会更短,像我们就是30。如果没有总长度字段,那么IP层就不知道46字节中有多少是IP数据报的内容。所以IP包总长度这个字段是一定需要的.
  • 5,6字节, Identification. 0xd431=54321.
  • 7,8字节, 0000.
  • 9字节, 20. TTL. 路由转发此IP包的时候就把这个数值减1, 减到0的时候就直接丢弃, 并发送ICMP通知主机. trouceroute即利用了这个.
  • 10字节, 06, 代表TCP协议.
  • 11,12字节 c8a6. Checksum.
  • 13–16字节, 7f00 0001. Source Address. 代表127.0.0.1
  • 17–20字节, 7f00 0001. Destination Address. 代表127.0.0.1

Checksum是内核帮我们算好的, 但以后的TCP等就要自己算了, 这里先看一下算法.

首先把检验和字段置为 0。然后,对首部中每个 16 bit 进行二进制反码求和(整个首部看成是由一串 16 bit的字组成)

def checksum(ip_header):
    ip_header += chr(0x00)*(len(ip_header)%2)
    r = 0
    while ip_header:
        # 因为ip_header已经是网络序了, 所以这里用H. 否则需要用!H
        r += unpack(‘H‘,ip_header[:2])[0]
        ip_header = ip_header[2:]

    if r > 0xffff:
        r = r&0xffff + (r>>16);

    return ~r
时间: 2024-10-01 06:45:10

tcp/ip协议学习 第三章 IP协议的相关文章

oracle学习 第三章 常用的SQL*PLUS命令 ——02

今天接着昨天的RUN命令继续讲. 3.5 n(设置当前行)命令和A(PPEND)(附加)命令 设想,你输入了例3-10的查询语句 例 3-10 SQL> SELECT ename 2 FROM emp; 例 3-10 结果 看到以上输出时,您发现在SELECT子句中忘了job,sal.这时您又如何修改您的SELECT子句呢?首先您应该使用SQL*PLUS的L(LIST)命令来显示SQL缓冲中的内容. 例 3-11 SQL> L 例 3-11 结果 在例3-11显示的结果中,2后面的"

CCNA学习笔记三——STP生成树协议

广播风暴:当网络中存在物理环路,会产生广播风暴 STP协议:Spanning Tree Protocol(生成树协议) 逻辑上断开环路,防止广播风暴的产生 STP算法:(所有选择都是比小-小的当选) 选择根网桥(Root Bridge):在网络中的所有交换机中选择一台 选择依据:网桥ID(网桥优先级+MAC地址) 选择根端口(Root Ports):在所有非根网桥中选择一个 选择依据:(1)根路径成本最低 (2)直连网桥ID最小 (3)端口ID最小 选择指定端口(Designated Ports

安卓学习——第三章

安卓学习——第三章 由于自身的实力不足,经过尝试后放弃了自己编写记账本app,而是打算找到合适的相关项目进行学习.我找到了几个AndroidStudio项目,我在AndroidStudio里面直接打开文件,发现无法运行.想到应该是import项目才行(我可真是菜的真实). 通过import这些项目之后,发现其中一个项目竟然是可以跑起来的.我便将项目通过手机进行测试,发现在手机上也是可以运行的.不过有一些在外观上的问题. 首先是在手机上的显示,会有一部分文字内容是乱码.我便去找编译器里面相关文件的

tcp/ip协议第三章 ip:网际协议

tcp/ip协议第三章读后总结 ip是tcp/ip协议族中最为核心的协议.ip提供不可靠传输,不可靠的意思是它不保证ip数据包能成功的到达目的地.ip仅提供最好的传输服务.任何要求的可靠性必须由上层来提供(如tcp) 子网的划分缩小了internet路由表的规模,因为许多网络经常可以通过单个表目就可以访问了. 接口网络的有关信息通过ifcongif和netstat命令可以获得,包括接口的ip地址.子网掩码.广播地址.以及mtu等

TCP/IP协议第一卷第三章

IP介绍 IP是TCP/IP协议族中最为核心的协议.所有的TCP.UDP.ICMP.IGMP数据都以IP数据报格式传输. IP提供不可靠.无连接的数据报传送服务. 不可靠(unreliable)它不能保证IP数据报能够成功地到达目的地.IP仅提供最好的传输服务.如果发生某种错误时,如某个路由器暂时用完了缓冲区,IP有一个简单的错误处理算法:丢弃该数据报,然后发送ICMP消息报给信源端.任何要求可靠性必须由上层来提供(如TCP). 无连接(connectionless)IP并不维护任何关于后续数据

《TCP/IP详解卷1:协议》第3章 IP:网际协议(1)-读书笔记

章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 1.引言 IP是TCP/IP协议族中最核心的协议.所有的TCP.UDP.ICMP及IGMP数据都以IP数据报格式传输.IP提供不可靠.无连接的数据报传送服务. (1)不可靠 它不能保证IP数据报能成功地到达目的地.IP仅提供最好的传输服务.如果发生某种错误,如某个路由器暂时用完了缓冲区,IP有一个简单的错误处理算法:丢弃该数据报,然后发送ICMP消息报给信源端.

《TCP/IP详解卷1:协议》——第3章 IP:网际协议(转载)

1.引言 IP是TCP/IP协议族中最核心的协议.所有的TCP.UDP.ICMP及IGMP数据都以IP数据报格式传输.IP提供不可靠.无连接的数据报传送服务. (1)不可靠 它不能保证IP数据报能成功地到达目的地.IP仅提供最好的传输服务.如果发生某种错误,如某个路由器暂时用完了缓冲区,IP有一个简单的错误处理算法:丢弃该数据报,然后发送ICMP消息报给信源端.任何要求的可靠性必须由上层来提供(如TCP). (2)无连接 IP并不维护任何关于后续数据报的状态信息.每个数据报的处理是相互独立的.即

TCP/IP详解 卷一(第三章 IP:网际协议)

IP是TCP/IP协议族中最为核心的协议.所有的TCP.UDP.ICMP及IGMP数据都以IP数据报格式传输. IP提供不可靠.无连接的数据报传送服务. 1.不可靠:就是它不能保证IP数据报能成功地到达目的地.IP仅提供最好的传输服务. 2.无连接:每个数据报的处理都是相互独立的,IP数据报可以不按发送顺序接收. 1.IP首部 其中TTL(time-to-live)生存时间字段设置了数据报可以经过的最多路由器数. 一旦经过一个处理它的路由器,它的值就减去1.当该字段的值为0时,数据报就被丢弃.

TCP/IP网络编程、三次握手协议及socket编程

1.概念 2.三次握手协议