两天以来我一直在为此烦恼。我正在尝试将数据包内容与正则表达式 API 进行匹配:
packet_re = (r'.*RADIUS.*\s*Accounting(\s|-)Request.*(Framed(\s|-)IP(\s|-)Address.*Attribute.*Value: (?P<client_ip>\d+\.\d+\.\d+\.\d+))?.*(Username|User-Name)(\s|-)Attribute.*Value:\s*(?P<username>\S+).*')
packet1 = """
IP (tos 0x0, ttl 64, id 35592, offset 0, flags [DF], proto UDP (17), length 213)
10.10.10.1.41860 > 10.10.10.3.1813: [udp sum ok] RADIUS, length: 185
Accounting-Request (4), id: 0x0a, Authenticator: 41b3b548c4b7f65fe810544995620308
Framed-IP-Address Attribute (8), length: 6, Value: 10.10.10.11
0x0000: 0a0a 0a0b
User-Name Attribute (1), length: 14, Value: 005056969256
0x0000: 3030 3530 3536 3936 3932 3536
"""
result = search(packet_re, packet1, DOTALL)
Run Code Online (Sandbox Code Playgroud)
正则表达式匹配,但无法捕获Framed-IP-Address Attribute, client_ip=10.10.10.11。问题是Framed-IP-Address Attribute可以或不能放在包里。因此,该模式被包含在另一个以?0 或 1 次出现结尾的捕获组中。
当它没有出现时我应该能够忽略它。因此数据包内容也可以是:
packet2 = """
IP (tos 0x0, ttl 64, id 60162, offset 0, flags [DF], proto UDP (17), length 163)
20.20.20.1.54035 > 20.20.20.2.1813: [udp sum ok] RADIUS, length: 135
Accounting-Request (4), id: 0x01, Authenticator: 219b694bcff639221fa29940e8d2a4b2
User-Name Attribute (1), length: 14, Value: 005056962f54
0x0000: 3030 3530 3536 3936 3266 3534
"""
Run Code Online (Sandbox Code Playgroud)
在这种情况下,正则表达式应忽略 Framed-IP-Address。它确实会忽略,但不会捕获它何时到来。
我建议使用
RADIUS.*?Accounting[\s-]Request(?:.*?(Framed[\s-]IP[\s-]Address.*?Attribute(?:.*?Value: (?P<client_ip>\d+\.\d+\.\d+\.\d+))?))?.*User-?[nN]ame[\s-]Attribute.*?Value:\s*(?P<username>\S+)
Run Code Online (Sandbox Code Playgroud)
请参阅正则表达式演示。
注意,我删除了.*模式的两端,因为您使用的模式re.search不需要在字符串开头进行匹配,例如re.match,并且该MatchData对象包含您可以访问以获得整个输入字符串的.string属性。
细节
RADIUS- 一个字.*?- 任何零个或多个字符,尽可能少Accounting- 一个字[\s-]- 空格或连字符Request- 一个字(?:.*?- 可选非捕获组的开始:任何零个或多个尽可能少的字符,然后...
(Framed[\s-]IP[\s-]Address.*?Attribute- 第 1 组:Framed+ 空格或连字符 + IP+ 空格/连字符 + Address+ 任何零个或多个尽可能少的字符 +Attribute
(?:.*?Value: (?P<client_ip>\d+\.\d+\.\d+\.\d+))?- 一个可选的非捕获组,匹配尽可能少的任何零个或多个字符 + Value: + 组“client_ip”:四个一位或多位数字匹配模式,用文字点分隔)- 第 1 组结束)?- 外部非捕获组的末尾.*- 任何零个或多个尽可能多的字符User-?[nN]ame - Username,UserName或者User-name/User-Name[\s-]- 空格或连字符Attribute- 一个字.*?- 任何零个或多个尽可能少的字符Value:- 文字字符串\s*- 零个或多个空格(?P<username>\S+)- 组“用户名”:一个或多个非空白字符