Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
scapy
Manage
Activity
Members
Plan
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CodeLinaro
public-release-test-restored
platform
external
scapy
Commits
fcb62e79
Commit
fcb62e79
authored
8 years ago
by
Benjamin
Committed by
Pierre Lalet
8 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Fix issue #359: Bin to str conversion of IPv6 addresses (#431)
parent
5322d88c
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
scapy/pton_ntop.py
+24
-24
24 additions, 24 deletions
scapy/pton_ntop.py
test/regression.uts
+76
-0
76 additions, 0 deletions
test/regression.uts
with
100 additions
and
24 deletions
scapy/pton_ntop.py
+
24
−
24
View file @
fcb62e79
...
...
@@ -10,7 +10,10 @@ These functions are missing when python is compiled
without IPv6 support, on Windows for instance.
"""
import
socket
,
struct
import
socket
import
re
_IP6_ZEROS
=
re
.
compile
(
'
(?::|^)(0(?::0)+)(?::|$)
'
)
def
inet_pton
(
af
,
addr
):
"""
Convert an IP address from text representation into binary form
"""
...
...
@@ -75,27 +78,24 @@ def inet_ntop(af, addr):
try
:
return
socket
.
inet_ntop
(
af
,
addr
)
except
AttributeError
:
pass
# IPv6 addresses have 128bits (16 bytes)
if
len
(
addr
)
!=
16
:
raise
Exception
(
"
Illegal syntax for IP address
"
)
parts
=
[]
for
left
in
[
0
,
2
,
4
,
6
,
8
,
10
,
12
,
14
]:
try
:
value
=
struct
.
unpack
(
"
!H
"
,
addr
[
left
:
left
+
2
])[
0
]
hexstr
=
hex
(
value
)[
2
:]
except
TypeError
:
raise
Exception
(
"
Illegal syntax for IP address
"
)
parts
.
append
(
hexstr
.
lstrip
(
"
0
"
).
lower
())
result
=
"
:
"
.
join
(
parts
)
while
"
:::
"
in
result
:
result
=
result
.
replace
(
"
:::
"
,
"
::
"
)
# Leaving out leading and trailing zeros is only allowed with ::
if
result
.
endswith
(
"
:
"
)
and
not
result
.
endswith
(
"
::
"
):
result
=
result
+
"
0
"
if
result
.
startswith
(
"
:
"
)
and
not
result
.
startswith
(
"
::
"
):
result
=
"
0
"
+
result
return
result
return
_ipv6_bin_to_str
(
addr
)
else
:
raise
Exception
(
"
Address family not supported yet
"
)
raise
Exception
(
"
Address family not supported yet
"
)
def
_ipv6_bin_to_str
(
addr
):
# IPv6 addresses have 128bits (16 bytes)
if
len
(
addr
)
!=
16
:
raise
ValueError
(
"
invalid length of packed IP address string
"
)
# Decode to hex representation
address
=
"
:
"
.
join
(
addr
[
idx
:
idx
+
2
].
encode
(
'
hex
'
).
lstrip
(
'
0
'
)
or
'
0
'
for
idx
in
xrange
(
0
,
16
,
2
))
try
:
# Get the longest set of zero blocks
# Actually we need to take a look at group 1 regarding the length as 0:0:1:0:0:2:3:4 would have two matches:
# 0:0: and :0:0: where the latter is longer, though the first one should be taken. Group 1 is in both cases 0:0.
match
=
max
(
_IP6_ZEROS
.
finditer
(
address
),
key
=
lambda
m
:
m
.
end
(
1
)
-
m
.
start
(
1
))
return
'
{}::{}
'
.
format
(
address
[:
match
.
start
()],
address
[
match
.
end
():])
except
ValueError
:
return
address
This diff is collapsed.
Click to expand it.
test/regression.uts
+
76
−
0
View file @
fcb62e79
...
...
@@ -7047,3 +7047,79 @@ x = f.i2repr(mp, {'*', '+', 'bit 2'})
assert(re.match(r'^.*Star \(\*\).*$', x) is not None)
assert(re.match(r'^.*Plus \(\+\).*$', x) is not None)
assert(re.match(r'^.*bit 2.*$', x) is not None)
###########################################################################################################
+ Test correct conversion from binary to string of IPv6 addresses
= IPv6 bin to string conversion - all zero bytes
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # All zero
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '::')
= IPv6 bin to string conversion - non-compressable
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x77\x77\x88\x88' # Not compressable
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1111:2222:3333:4444:5555:6666:7777:8888')
= IPv6 bin to string conversion - Zero-block right
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x00\x00\x00\x00\x00\x00' # Zeroblock right
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1111:2222:3333:4444:5555::')
= IPv6 bin to string conversion - Zero-block left
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x00\x00\x00\x00\x00\x44\x44\x55\x55\x66\x66\x77\x77\x88\x88' # Zeroblock left
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '::4444:5555:6666:7777:8888')
= IPv6 bin to string conversion - Two zero-block with different length
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x00\x00\x00\x33\x33\x44\x44\x00\x00\x00\x00\x00\x00\x88\x88' # Short and long zero block
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '0:0:3333:4444::8888')
= IPv6 bin to string conversion - Address 1::
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # only 1 on the left
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1::')
= IPv6 bin to string conversion - Address ::1
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' # loopback
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '::1')
= IPv6 bin to string conversion - Zero-block of length 1
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x00\x00\x88\x88' # only one zero block
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == '1111:2222:3333:4444:5555:6666:0:8888')
# On Mac OS socket.inet_ntop is not fully compliant with RFC 5952 and shortens the single zero block to '::'. Still
# this is a valid IPv6 address representation.
assert(compressed2 in ('1111:2222:3333:4444:5555:6666:0:8888', '1111:2222:3333:4444:5555:6666::8888'))
= IPv6 bin to string conversion - Two zero-blocks with equal length
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x11\x11\x00\x00\x00\x00\x44\x44\x00\x00\x00\x00\x77\x77\x88\x88' # two zero blocks of equal length
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1111::4444:0:0:7777:8888')
= IPv6 bin to string conversion - Leading zero suppression
from scapy.pton_ntop import _ipv6_bin_to_str, inet_ntop
import socket
address=b'\x10\x00\x02\x00\x00\x30\x00\x04\x00\x05\x00\x60\x07\x00\x80\x00' # Leading zero suppression
compressed1, compressed2 = _ipv6_bin_to_str(address), inet_ntop(socket.AF_INET6, address)
assert(compressed1 == compressed2 == '1000:200:30:4:5:60:700:8000')
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment