From e2e44b9fcbe82ae7ecf36f3136163d1680bec8c0 Mon Sep 17 00:00:00 2001
From: Marcel Patzlaff <mpatzlaff@benocs.com>
Date: Mon, 22 Dec 2014 11:05:57 +0100
Subject: [PATCH] [arch.py] FIX: get_if_addr6() did return a wrong value
 CHANGE: get_if_raw_addr6() bases now on get_if_addr6()

[ospf.py]
FIX: re-inserted default values of IPv6 prefixes

[isis.py]
FIX: removed unnecessary length check

[fields.py]
NEW: added some comments to the IP prefix formats
FIX: unified machine representation of IP prefixes
---
 scapy/arch/__init__.py | 24 ++++++++++++------------
 scapy/contrib/isis.py  |  3 ---
 scapy/contrib/ospf.py  |  6 +++---
 scapy/fields.py        | 10 +++++++---
 4 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/scapy/arch/__init__.py b/scapy/arch/__init__.py
index bb3e3def..18c15771 100644
--- a/scapy/arch/__init__.py
+++ b/scapy/arch/__init__.py
@@ -85,13 +85,14 @@ if scapy.config.conf.iface is None:
 def get_if_addr6(iff):
     """
     Returns the main global unicast address associated with provided 
-    interface. If no global address is found, None is returned. 
+    interface, in human readable form. If no global address is found,
+    None is returned. 
     """
-    r = filter(lambda x: x[2] == iff and x[1] == IPV6_ADDR_GLOBAL, in6_getifaddr())
-    if len(r) == 0:
-        return None
-    else:
-        return r[0][0]
+    for x in in6_getifaddr():
+        if x[2] == iff and x[1] == IPV6_ADDR_GLOBAL:
+            return x[0]
+        
+    return None
 
 def get_if_raw_addr6(iff):
     """
@@ -99,9 +100,8 @@ def get_if_raw_addr6(iff):
     interface, in network format. If no global address is found, None 
     is returned. 
     """
-    r = filter(lambda x: x[2] == iff and x[1] == IPV6_ADDR_GLOBAL, in6_getifaddr())
-    if len(r) == 0:
-        return None
-    else:
-        r = r[0][0] 
-    return inet_pton(socket.AF_INET6, r)
+    ip6= get_if_addr6(iff)
+    if ip6 is not None:
+        return inet_pton(socket.AF_INET6, ip6)
+    
+    return None
diff --git a/scapy/contrib/isis.py b/scapy/contrib/isis.py
index 9fc0a3ad..1fb5dde6 100644
--- a/scapy/contrib/isis.py
+++ b/scapy/contrib/isis.py
@@ -70,9 +70,6 @@ conf.debug_dissector= True
 #######################################################################
 
 def isis_area2str(area):
-    if len(area) == 0:
-        return ""
-    
     return "".join(x.decode("hex") for x in area.split("."))
 
 def isis_str2area(s):
diff --git a/scapy/contrib/ospf.py b/scapy/contrib/ospf.py
index 4c886df3..362e467e 100644
--- a/scapy/contrib/ospf.py
+++ b/scapy/contrib/ospf.py
@@ -585,7 +585,7 @@ class OSPFv3_Inter_Area_Prefix_LSA(OSPF_BaseLSA):
                    FieldLenField("prefixlen", None, length_of="prefix", fmt="B"),
                    OSPFv3PrefixOptionsField(),
                    ShortField("reserved2", 0),
-                   IP6PrefixField("prefix", None, wordbytes=4, length_from=lambda pkt: pkt.prefixlen)]
+                   IP6PrefixField("prefix", "2001:db8:0:42::/64", wordbytes=4, length_from=lambda pkt: pkt.prefixlen)]
 
 
 class OSPFv3_Inter_Area_Router_LSA(OSPF_BaseLSA):
@@ -618,7 +618,7 @@ class OSPFv3_AS_External_LSA(OSPF_BaseLSA):
                    FieldLenField("prefixlen", None, length_of="prefix", fmt="B"),
                    OSPFv3PrefixOptionsField(),
                    ShortEnumField("reflstype", 0, _OSPFv3_LStypes),
-                   IP6PrefixField("prefix", None, wordbytes=4, length_from=lambda pkt: pkt.prefixlen),
+                   IP6PrefixField("prefix", "2001:db8:0:42::/64", wordbytes=4, length_from=lambda pkt: pkt.prefixlen),
                    ConditionalField(IP6Field("fwaddr", "::"), lambda pkt: pkt.flags & 0x02 == 0x02),
                    ConditionalField(IntField("tag", 0), lambda pkt: pkt.flags & 0x01 == 0x01),
                    ConditionalField(IPField("reflsid", 0), lambda pkt: pkt.reflstype != 0)]
@@ -634,7 +634,7 @@ class OSPFv3_Prefix_Item(Packet):
     fields_desc = [FieldLenField("prefixlen", None, length_of="prefix", fmt="B"),
                    OSPFv3PrefixOptionsField(),
                    ShortField("metric", 10),
-                   IP6PrefixField("prefix", None, wordbytes=4, length_from=lambda pkt: pkt.prefixlen)]
+                   IP6PrefixField("prefix", "2001:db8:0:42::/64", wordbytes=4, length_from=lambda pkt: pkt.prefixlen)]
 
     def extract_padding(self, s):
         return "", s
diff --git a/scapy/fields.py b/scapy/fields.py
index 2073c262..7ad0a4cf 100644
--- a/scapy/fields.py
+++ b/scapy/fields.py
@@ -928,21 +928,25 @@ class _IPPrefixFieldBase(Field):
         return ((pfxlen + (wbits - 1)) / wbits) * self.wordbytes
     
     def h2i(self, pkt, x):
+        # "fc00:1::1/64" -> ("fc00:1::1", 64)
         [pfx,pfxlen]= x.split('/')
         self.aton(pfx) # check for validity
         return (pfx, int(pfxlen))
 
 
     def i2h(self, pkt, x):
+        # ("fc00:1::1", 64) -> "fc00:1::1/64"
         (pfx,pfxlen)= x
         return "%s/%i" % (pfx,pfxlen)
 
     def i2m(self, pkt, x):
+        # ("fc00:1::1", 64) -> ("\xfc\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 64)
         (pfx,pfxlen)= x
         s= self.aton(pfx);
-        return s[:self._numbytes(pfxlen)]
+        return (s[:self._numbytes(pfxlen)], pfxlen)
     
     def m2i(self, pkt, x):
+        # ("\xfc\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 64) -> ("fc00:1::1", 64)
         (s,pfxlen)= x
         
         if len(s) < self.maxbytes:
@@ -960,9 +964,9 @@ class _IPPrefixFieldBase(Field):
         return pfxlen
         
     def addfield(self, pkt, s, val):
-        (_,pfxlen)= val
+        (rawpfx,pfxlen)= self.i2m(pkt,val)
         fmt= "!%is" % self._numbytes(pfxlen)
-        return s+struct.pack(fmt, self.i2m(pkt,val))
+        return s+struct.pack(fmt, rawpfx)
     
     def getfield(self, pkt, s):
         pfxlen= self.length_from(pkt)
-- 
GitLab