【问题标题】:How can I convert an IPv4 address from bytes to a string without using a loop?如何在不使用循环的情况下将 IPv4 地址从字节转换为字符串?
【发布时间】:2019-06-04 08:25:15
【问题描述】:

我有一个简单的 python 脚本,它创建一个套接字 AF_PACKET,它解析所有 IPv4 数据包并检索源和目标 IP 地址:

import socket
import struct

def get_ip(s):
    return '.'.join([str(ord(symbol)) for symbol in s])

def main():
    conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))

    while True:
    pkt, addr = conn.recvfrom(65536)

    proto = struct.unpack('! H', pkt[12:14])
    eth_proto = socket.htons(proto[0])

    print('eth_proto = ', eth_proto)
    if eth_proto == 8:
        src, target = struct.unpack('! 4s 4s', pkt[26:34])
        source_ip = get_ip(src)
        destination_ip = get_ip(target)

        print('Source IP = ', source_ip)
        print('Destination IP = ', destination_ip)

main()

是否可以重构获取IP地址,这样看起来会更好,不使用这个循环:

'.'.join([str(ord(symbol)) for symbol in s])

此处描述了格式字符: https://docs.python.org/2/library/struct.html

【问题讨论】:

  • 请显示get_ip 函数的示例输入和所需的输出。
  • @ruohola 函数 get_ip 的输出是带有 ip 地址的字符串(例如 172.15.75.12),输入是字节数组。也许我可以用不同的方式读取这个字节?

标签: python sockets parsing packet unpack


【解决方案1】:

如果您使用的是 Python 2(因为您已链接到 Python 2 文档),则可以使用字节数组和格式字符串来删除显式循环。

>>> s = '\n\x0b\xfa\x01'
>>> '{}.{}.{}.{}'.format(*bytearray(s))
'10.11.250.1'

如果您使用的是 Python 3.3+,则可以使用标准库的 ipaddress 模块。

>> ipa2 = ipaddress.ip_address(b'\n\x0b\xfa\x01')
>>> ipa2
IPv4Address('10.11.250.1')
>>> str(ipa2)
'10.11.250.1'

【讨论】:

    猜你喜欢
    • 2014-03-30
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多