python解压缓冲区数据

标签 python linux tcp dhcp

我在 radius 中使用 rlm_python 模块,它以十六进制或二进制格式从 coovachilli 获取 DHCP 位置 option82

将其捕获为字符串显示为此值 \001\027\002\025\001+\001\024,但看起来 python 显示的值被截断了,因为 option82 包含以 TLVs-type,length,values 编码的 suboptions 这意味着该字段以 0x01 类型开始(电路 ID,根据 RFC 3046),后跟一个字节的长度。

知道如何捕获它并正确解压缩选项吗?

我已经使用 struct.unpack 解压了字符串,但没有意义..因为它没有说明 option82 中的打包 suboptions字段。

Python 2.4.3 (#1, May  5 2011, 16:39:10) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from struct import *
>>> unpack('=hhl',"\001\027\002\025\001+\001\024" )
(5889, 5378, 335620865)

有什么想法吗?

更新:

Coovachilli 是用 --locationopt82 编译的,它将位置作为属性发送,就像这样......

rad_recv: Accounting-Request packet from host 10.66.53.49 port 53178, id=101, length=342
        ChilliSpot-Version = "1.3.0"
        ChilliSpot-Acct-View-Point = ChilliSpot-Client-View-Point
        Event-Timestamp = "Apr 18 2013 11:59:16 BST"
        User-Name = "3C-D0-F8-4A-05-68"
        Acct-Input-Octets = 0
        Acct-Output-Octets = 22851
        Acct-Input-Gigawords = 0
        Acct-Output-Gigawords = 0
        Acct-Input-Packets = 0
        Acct-Output-Packets = 370
        Acct-Session-Time = 5401
        ChilliSpot-Session-State = Authorized
        Acct-Status-Type = Interim-Update
        Acct-Session-Id = "516fbceb00000002"
        Framed-IP-Address = 10.75.33.46
        NAS-Port-Type = Wireless-802.11
        NAS-Port = 2
        NAS-Port-Id = "00000002"
        Calling-Station-Id = "3C-D0-F8-4A-05-68"
        Called-Station-Id = "00-50-56-B7-66-00"
        NAS-IP-Address = 10.75.32.7
        ChilliSpot-Location = "\001\030\002\026\001+\001\024"
        ChilliSpot-Location-Change-Count = 15
        NAS-Identifier = "VLAN299-REGENT"
        WISPr-Location-ID = "isocc=GR,cc=44,ac=01200,network=mywifi,my_Network_regent"
        WISPr-Location-Name = "REGENT"

freeradius 有 rlm_python 模块,它可以查找记帐请求

def accounting(p):
    file = open("/tmp/test.log","a")
    username = None
    chillilocation = None
    output = StringIO.StringIO()

    for t in p:
        if t[0] == 'User-Name':
            username = t[1]
        elif t[0] == 'ChilliSpot-Location':
            chillilocation = t[1]a
             output.write(t[1])


    content = output.getvalue()


    file.write("I am being called in radius accouting section as %s and location is %s \n" % (username,content))
    file.close()
    print "---Accounting---"
    radiusd.radlog(radiusd.L_INFO, '*** radlog call in accounting (0) ***')
    print
    print p
    return radiusd.RLM_MODULE_OK

我已经尝试将 ChilliSpot-Location 存储在 stringstringIO 中,使用 struct 解压但无济于事,它看起来像是 TLV 格式...

有什么想法可以去掉吗?

最佳答案

解包不会解包为“有意义的”值。它将字符串解压缩为一系列数字字段,以便每个字段的大小由格式字符串的每个字符指定(字母前面的数字是乘数)。

解包不应该使用八位字节大小的字段吗?

>>> unpack('=8B',"\001\027\002\025\001+\001\024")
(1, 23, 2, 21, 1, 43, 1, 20)
# Or maybe '+' is a separator (43):
>>> unpack('=6Bh',"\001\027\002\025\001+\001\024")
(1, 23, 2, 21, 1, 43, 5121)

第一个字节可能是电路子选项代码 (unpack()[0]==1),其大小高得惊人,为 23,这意味着我们没有获得整个子选项值。但我们也可能只有大小 == 10 或 8 字节内容的子选项的包含值。

我不太确定选项 82 是否应该包含可读字符串,但“ChilliSpot-Location”确实如此。 RFC3046 表示电路子选项应包含诸如“路由器接口(interface)号”、端口号和其他数值之类的内容。但是 rad_recv 的那个属性真的来自 82 选项吗?

关于python解压缓冲区数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15908541/

相关文章:

java - SQLITE_ERROR SQL 错误或缺少数据库( "VALUES"附近 : syntax error)

c - 为什么添加 send() 调用会使之前的 send() 调用失败?

tcp - 如何在 Mac 上打开 80 端口?

python - 类型错误:无法连接 'str' 和 'float' 对象

linux - 程序集中未知大小的缓冲区

Python ggplot- ggsave 函数未定义

linux - 如何让VIM接收并显示正在运行的程序的输出?

linux - 巴什 : merge two directories and delete duplicated data

python - Sympy ODE 求解器初始条件无效

python - 将从一列中提取以 "Unit"开头的字符串并将其复制到新列 : Pandas