pcap发包器

前言

	实时会议中,需要对音视频的rtp码流进行重放。所以写了一个rtp发包器脚本

pcap发包器

# -*- coding: utf-8 -*-
#v1:支持循环发包
#v2:支持发送linux格式包(链路层头不同非eth)
#v3:修复ip pad导致发包器崩溃问题
#v4:支持按照原先节奏发包
#v5:区分ipv4和ipv6
# --yjj 2019/11/21
# 环境:python2/3
import socket
import binascii
import time
import os

ipv = 0 #默认 ipv4 格式 ipv4 0 ipv6 1

if ipv == 0:
    IP = "xxx.xx.xx.xxx"
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    iplen = 20
else:
    IP = "fe80::548f:7fe5:7db7:bc26"
    s = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM)
    iplen = 40
PORT = 4000

s.bind((IP,6000))
i = 0
j = 0
boom = 0
skip = 0

Linux_or_Win = 0 #默认 Win 格式 win 0 linux 1
choose_loop = 0 #参数0 只发送一次

f = open('D:\\2565_eth.pcap','rb')
fsize = os.path.getsize('D:\\2565_eth.pcap')

ff = open('D:\medialen','w')

while True:
        f.read(24) #pacp头
        i = i + 1
        if choose_loop == 0:
            if i == 2:
                break
        while True:
                print("Send %d times" % (i))
                j = j + 1
                skip = skip + 1
                print("NO.%d" % (j))
                high = f.read(4) #数据报头16
                high = binascii.b2a_hex(high).decode('utf-16-be')[::-1].encode('utf-16-be')
                low = f.read(4)
                low = binascii.b2a_hex(low).decode('utf-16-be')[::-1].encode('utf-16-be')
                timesth = int(high,16)
                timestl = int(low,16)
                timeReal = timesth + timestl*0.000001
                if skip > 1:
                    intv = timeReal - boom
                else:
                    intv = 0
                print("last packet to this packet intv : %f " % (intv))
                boom = timeReal
                rlen = f.read(4)
                trlen = binascii.b2a_hex(rlen).decode('utf-16-be')[::-1].encode('utf-16-be')
                #binascii.b2a_hex的作用是把二进制的数据转为十六进制的字符串
                #但是这里转出来的十六进制数据得由大端序转为小端序
                #decode('hex')[::-1]的作用是将字符串以十六进制编码格式解码,并且倒序
                #encode('hex')是将字符串按照十六进制格式编码
                dtrlen = int(trlen,16)
                print("This packet real-length : %d " % (dtrlen))
                f.read(4)
                if Linux_or_Win == 1:
                    f.read(16) #以太网帧头16 linux
                    sum = 16 + 8 + iplen
                else:
                    f.read(14) #以太网帧头14 win
                    sum = 14 + 8 + iplen
                f.read(iplen) #ipv4头20 ipv6头40
                f.read(4)
                n = f.read(2)
                t = binascii.b2a_hex(n)
                dec = int(t,16)
                f.read(2) #udp头 8字节 ps:tcp 20字节
                dec = dec - 8
                print("RTP Packet length: %d " % (dec))
                if dec > 1500:
                    print("Warning: this packet is so big !!!")
                elif dec <= 0:
                    print("Errors: this packet maybe wrong !!!")
                n = f.read(dec)
                size = f.tell()
                print("The location of the Rtp packet in the file: %d " % (size))
                print("....................................................")
                if intv >= 0.001:
                    time.sleep(0.8*intv)
                #if (j % 2) == 0 :
                #    s.sendto(n,(IP,PORT)) #j参数的作用是为了过滤多倍包,但是乱序/丢包,会影响使用
                s.sendto(n,(IP,PORT))
                tbt = dec-12
                ff.write("\n%d" % (tbt))
                if size >= fsize:
                    f.seek(0)
                    j = 0
                    skip = 0
                    boom = 0
                    break
                else:
                    padlength = dtrlen - sum - dec #sum为以太网帧头eth14 + ip头20 + udp头8
                    print(padlength)
                    f.read(padlength)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值