Python网络编程3--实现IP源站路由

一、IP报文首部格式

IP首部
  • 字段解释
    • Version
      4:表示为IPV4;
      6:表示为IPV6。
    • IHL
      首部长度,如果不带Option字段,则为20,最长为60,该值限制了记录路由选项。以4字节为一个单位。
    • Type of Service
      服务类型。只有在有QoS差分服务要求时这个字段才起作用。
    • Total Length
      总长度,整个IP数据报的长度,包括首部和数据之和,单位为字节,最长65535,总长度必须不超过最大传输单元MTU。
    • Identification
      标识,主机每发一个报文,加1,分片重组时会用到该字段。
    • Flags
      标志位:
      Bit 0: 保留位,必须为0。
      Bit 1: DF(Don't Fragment),能否分片位,0表示可以分片,1表示不能分片。
      Bit 2: MF(More Fragment),表示是否该报文为最后一片,0表示最后一片,1代表后面还有。
    • Fragment Offset
      片偏移:分片重组时会用到该字段。表示较长的分组在分片后,某片在原分组中的相对位置。以8个字节为偏移单位。
    • Time to Live
      生存时间:可经过的最多路由数,即数据包在网络中可通过的路由器数的最大值。
    • Protocol
      协议:下一层协议。指出此数据包携带的数据使用何种协议,以便目的主机的IP层将数据部分上交给哪个进程处理。
    • Header Checksum
      首部检验和,只检验数据包的首部,不检验数据部分。这里不采用CRC检验码,而采用简单的计算方法。
    • Source Address
      源IP地址。
    • Destination Address
      目的IP地址。
    • Options
      可变 选项字段,用来支持排错,测量以及安全等措施,内容丰富。选项字段长度可变,从1字节到40字节不等,取决于所选项的功能。
    • Padding
      可变 填充字段,全填0。

二、实现IP源站路由

2.1 源站路由

  源站路由可以事先规定IP数据包所经过得路由器,每经过一个路由器就改变数据包的目的地址(下一跳)
  使用IP头部中的option字段记录路由IP。该字段最大40字节,因此最多存放9个IP,记录格式如下:


源站路由

Type:占1字节,code 的值此处设为137。

  • 严格:0x89,清单中的相连两个地址,经过的路由器必须是直连的(因此此时路由器不需要有路由就能转发该数据包),如果所指下一跳不在路由器的直连网络中,将返回一个“源站路由失败”的ICMP差错报文。
  • 宽松:0x83,清单中的相连两个地址,可以经过几个路由器到达

length:占1字节,记录整个选项的长度。
pointer:指针项,占1个字节,指向下一个被处理的源站地址,最小值为4。

2.2 运行过程

  发送主机从应用程序接收源站路由清单,最后一个表项(它是数据报的最终目的地址),剩余的为所有经过的下一跳,每经过一个设备都会检查是否是最终目标,如不是则从列表中读取下一项作为数据包下一跳的目的地址,同时数据包每从一个路由器发出,就记录其出接口的地址,用其替换掉清单中的上一跳地址,数据包返回时任然按照原来的路径返回。
  如下图,主机S上的发送应用程序发送一份数据报给D,指定源路由为R1,R2和R3。#表示指针字段,其值分别是4、8、12和16(一个值表示一个32位IP)。长度字段恒为1 5(三个IP地址加上三个字节首部)。可以看出,每一跳IP数据报中的目的地址都发生改变。


IP源路由

2.3 Python实现

  • 实验环境
    在Ensp上搭建测试网络,其中各路由器上只有直连路由。
    源路由实验
  • Python脚本
#!/usr/bin/python3.4
# -*- coding=utf-8 -*-

from kamene.all import *
import struct

def ip_sec(ip):
    '''对IP地址进行Bytes转换'''
    ip_l = ip.split(".")
    a = struct.pack(">B", int(ip_l[0]))
    b = struct.pack(">B", int(ip_l[1]))
    c = struct.pack(">B", int(ip_l[2]))
    d = struct.pack(">B", int(ip_l[3]))
    return a + b + c + d

def try_lsrr(dst,lsrr_hop):
    r2=ip_sec(lsrr_hop[1])
    D=ip_sec(dst)
    ip_options = b'\x83\x0B\x04'+r2+D+b"\x00"
    #\x83表示宽松源站路由,\x0B表示长度,\x04表示指针,紧跟着四个字节的IP地址(真正的目的地址),\x00补齐8字节边作为结束位。
    #长度为:3(前options前3字节)+8(r2+D)字节
    pkt = IP(dst=lsrr_hop[0], options=IPOption(ip_options))/ICMP(type=8,code=0)
    #目的地址为源站路由的地址,正真的目的地址放在IP选项内
    a=sr1(pkt,timeout = 1, verbose=True)
    result = a
if __name__ == '__main__':
    dest=input("目的IP>>>")
    lsr_route=input("经过的下一跳>>>")
    lsr_hop=lsr_route.split(" ")
    try_lsrr(dest, lsr_hop)
  • 执行效果
    在Pycharm上执行脚本。
    运行效果

    在R1-R2间抓包,可以看到此时request包当前目的为172.16.10.2,IP option中下一跳指向172.16.20.2,实际目标地址为172.16.30.2。
    R1-R2

    在R2-R3之间抓包,此时request包当前目的变为了172.16.20.2,IP Options中记录上一跳的出接口地址172.16.20.1,实际目的地址为172.16.30.2.
    R2-R3

    在R3-R4之间抓包,此时request包马上到达目标地址172.16.30.2,IP Options中记录着前两跳的出接口地址。
    R3-R4

    再看reply包,目的地址为172.16.16.30,IP Options中下一跳为172.16.20.1,实际目标地址为192.168.10.112.
    Reply
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容