我使用Scapy来操纵CoAP数据包。现在我发现了一件我想要做的事情,我实际上无法弄清楚如何。
我有以下CoAP数据包:
>>> pkt
<CoAP ver=1L type=CON tkl=8L code=PUT msg_id=<RandShort> token=<RandBin> options=[('If-Match', '\x04\xfc\xbbL'), ('Content-Format', ''), ('Uri-Path', '.well-known'), ('Uri-Path', 'core')] paymark='\xff' |<Raw load='CC22 at 12:39:31.495' |>>
>>> str(pkt)
'H\x03\xf4\x08\xbdR_\x85\xa3\x04\xe9\xe9\x14\x04\xfc\xbbL\xab.well-known\x04core\x10\xffCC22 at 12:39:31.495'
我现在要做的是将表示索引1 ''
处的选项的整个部分(不是选项值('Content-Format', '')
)替换为null(\x00
)字符。我知道此部分在str(pkt)[-22:-21]
的末尾附近由str(pkt)
表示,其值\x10
代表内容格式选项,但没有实际值。
所以,我想知道:有没有办法从高级字段(\x10
)获取str(pkt)[-22:-21]
(实际上,获取引用pkt.options[1]
),所以我可以替换这部分字符串由另一个值组成?
提前致谢!
答案 0 :(得分:1)
好的,问题几个小时后我想出了一个解决方案,如果我认为通过Scapy本身没有简单的方法可以做到这一点(可能是由于CoAP选项在CoAP中的实现方式)贡献层),似乎是一个公平的。
以下函数可用于“取消”整个CoAP选项字段:
def coap_option_to_null(pkt, opt_idx):
''' Changes the whole CoAP Option field at @opt_idx to null '''
opt = pkt.options[opt_idx]
l = pkt.options
# Sort the list of options by option number
l.sort( lambda x, y: cmp(coap_options[1][x[0]], coap_options[1][y[0]]) )
# Replace options for the sorted one and grabs new opt_idx
pkt.options = l
opt_idx = pkt.options.index(opt)
cur_delta = 0
opt_total_len = []
for opt in pkt.options:
if (option_model[opt[0]][0] - cur_delta) < 13:
delta_extended = 0
elif (option_model[opt[0]][0] - cur_delta) < 269:
delta_extended = 1
else:
delta_extended = 2
cur_delta += (option_model[opt[0]][0] - cur_delta)
if len(opt[1]) < 13:
len_extended = 0
elif len(opt[1]) < 269:
len_extended = 1
else:
len_extended = 2
opt_total_len.append(1+delta_extended+len_extended+len(opt[1]))
opt_lidx = sum(opt_total_len[:opt_idx])
opt_hidx = sum(opt_total_len[opt_idx+1:])
new_pkt = str(pkt)[:4+pkt.tkl+opt_lidx] + '\x00'*opt_total_len[opt_idx] + str(pkt)[-(len(pkt.payload)+1+sum(opt_total_len[opt_idx+1:])):]
return CoAP(new_pkt)
以下是演示:
>>> pkt
<CoAP ver=1L type=CON tkl=8L code=PUT msg_id=<RandShort> token=<RandBin> options=[('If-Match', '\x04\xfc\xbbL'), ('Content-Format', ''), ('Uri-Path', 'separate')] paymark='\xff' |<Raw load='CC22 at 12:39:31.495' |>>
>>> str(pkt)
'H\x03*\x88%T\xbe\xac\xd9\xee\xcd\xbd\x14\x04\xfc\xbbL\xa8separate\x10\xffCC22 at 12:39:31.495'
>>> npkt = coap_option_to_null(pkt, 1)
>>> npkt
<CoAP ver=1L type=CON tkl=8L code=PUT msg_id=47784 token='\x90L\x0f\xd4u\xbe&\xd7' options=[('If-Match', '\x04\xfc\xbbL'), ('Uri-Path', 'separate'), ('Uri-Path', '')] paymark='\xff' |<Raw load='CC22 at 12:39:31.495' |>>
>>> str(npkt)
'H\x03\xba\xa8\x90L\x0f\xd4u\xbe&\xd7\x14\x04\xfc\xbbL\xa8separate\x00\xffCC22 at 12:39:31.495'
>>> pkt
<CoAP ver=1L type=CON tkl=8L code=PUT msg_id=<RandShort> token=<RandBin> options=[('If-Match', '\x04\xfc\xbbL'), ('Content-Format', ''), ('Uri-Path', 'separate')] paymark='\xff' |<Raw load='CC22 at 12:39:31.495' |>>
>>> npkt = coap_option_to_null(pkt, 0)
>>> npkt
<CoAP ver=1L type=CON tkl=8L code=PUT msg_id=14606 token='s\xad\xd0\xf5\x05\xac\x87C' options=[(0L, ''), (0L, ''), (0L, ''), (0L, ''), (0L, ''), (10L, 'separate'), ('Uri-Path', '')] paymark='\xff' |<Raw load='CC22 at 12:39:31.495' |>>
>>> str(npkt)
'H\x039\x0es\xad\xd0\xf5\x05\xac\x87C\x00\x00\x00\x00\x00\xa8separate\x10\xffCC22 at 12:39:31.495'