diff --git a/scapy/fields.py b/scapy/fields.py
index 91df1adaa4d6927c1e14e8a2bc784fd33454c2b1..fa6cba4d7ad22a90bd80da8fb9bb0c177b7c8280 100644
--- a/scapy/fields.py
+++ b/scapy/fields.py
@@ -372,7 +372,6 @@ class PacketField(StrField):
         return remain,i
     
 class PacketLenField(PacketField):
-    holds_packets=1
     def __init__(self, name, default, cls, length_from=None):
         PacketField.__init__(self, name, default, cls)
         self.length_from = length_from
@@ -389,7 +388,6 @@ class PacketLenField(PacketField):
 
 class PacketListField(PacketField):
     islist = 1
-    holds_packets=1
     def __init__(self, name, default, cls, count_from=None, length_from=None):
         if default is None:
             default = []  # Create a new list for each instance
diff --git a/scapy/layers/dhcp6.py b/scapy/layers/dhcp6.py
index 2bd215d055d3877185c895f2ed83b238a41d3ac2..fba74898b7b61ea1926f6a9425c5620f51461e0d 100644
--- a/scapy/layers/dhcp6.py
+++ b/scapy/layers/dhcp6.py
@@ -256,7 +256,6 @@ class DHCP6OptUnknown(_DHCP6OptGuessPayload): # A generic DHCPv6 Option
                                 length_from = lambda pkt: pkt.optlen)]
 
 class _DUIDField(PacketField):
-    holds_packets=1
     def __init__(self, name, default, length_from=None):
         StrField.__init__(self, name, default)
         self.length_from = length_from
diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py
index 533db6c20c2bc4f1bae02e926abf785a9ba6ce1e..9c5f69e86825bb85e99ad4a350b7a0ce52d92d57 100644
--- a/scapy/layers/dns.py
+++ b/scapy/layers/dns.py
@@ -52,7 +52,6 @@ class DNSStrField(StrField):
 
 
 class DNSRRCountField(ShortField):
-    holds_packets=1
     def __init__(self, name, default, rr):
         ShortField.__init__(self, name, default)
         self.rr = rr
@@ -158,7 +157,6 @@ class DNSRRField(StrField):
             
             
 class DNSQRField(DNSRRField):
-    holds_packets=1
     def decodeRR(self, name, s, p):
         ret = s[p:p+4]
         p += 4
diff --git a/scapy/layers/inet6.py b/scapy/layers/inet6.py
index 5346a1f3235e2931d002d79fcb1640533184d7b7..28978fe49b3a1add3d290773f315be03d2a82586 100644
--- a/scapy/layers/inet6.py
+++ b/scapy/layers/inet6.py
@@ -741,8 +741,6 @@ _hbhoptcls = { 0x00: Pad1,
 ######################## Hop-by-Hop Extension Header ########################
 
 class _HopByHopOptionsField(PacketListField):
-    islist = 1
-    holds_packet = 1
     def __init__(self, name, default, cls, curpos, count_from=None, length_from=None):
         self.curpos = curpos
         PacketListField.__init__(self, name, default, cls, count_from=count_from, length_from=length_from)
@@ -2609,9 +2607,6 @@ class MIP6MH_Generic(_MobilityHeader): # Mainly for decoding of unknown msg
     
 # TODO: make a generic _OptionsField
 class _MobilityOptionsField(PacketListField):
-    islist = 1
-    holds_packet = 1
-
     def __init__(self, name, default, cls, curpos, count_from=None, length_from=None):
         self.curpos = curpos
         PacketListField.__init__(self, name, default, cls, count_from=count_from, length_from=length_from)
diff --git a/scapy/layers/sctp.py b/scapy/layers/sctp.py
index 632becb1bdca08ab5d6ec08170e15db3c8e856c0..299e49c1d3d85926c94b0d7e411097094fb0ab5e 100644
--- a/scapy/layers/sctp.py
+++ b/scapy/layers/sctp.py
@@ -207,8 +207,6 @@ class SCTP(_SCTPChunkGuessPayload, Packet):
 ############## SCTP Chunk variable params
 
 class ChunkParamField(PacketListField):
-    islist = 1
-    holds_packets=1
     def __init__(self, name, default, count_from=None, length_from=None):
         PacketListField.__init__(self, name, default, conf.raw_layer, count_from=count_from, length_from=length_from)
     def m2i(self, p, m):
diff --git a/scapy/packet.py b/scapy/packet.py
index 6c2094f27b2000de5923ffe0ec19e351f79de8da..bab03eef6838ce5203aa68cd62bcca5897a3890f 100644
--- a/scapy/packet.py
+++ b/scapy/packet.py
@@ -49,6 +49,7 @@ class Packet(BasePacket):
     show_indent=1
     explicit = 0
     raw_packet_cache = None
+    raw_packet_cache_fields = None
 
     @classmethod
     def from_hexcap(cls):
@@ -144,15 +145,16 @@ class Packet(BasePacket):
     def copy(self):
         """Returns a deep copy of the instance."""
         clone = self.__class__()
-        clone.fields = self.fields.copy()
-        for k in clone.fields:
-            clone.fields[k] = self.get_field(k).do_copy(clone.fields[k])
-        clone.default_fields = self.default_fields.copy()
+        clone.fields = self.copy_fields_dict(self.fields)
+        clone.default_fields = self.copy_fields_dict(self.default_fields)
         clone.overloaded_fields = self.overloaded_fields.copy()
         clone.overload_fields = self.overload_fields.copy()
         clone.underlayer = self.underlayer
         clone.explicit = self.explicit
         clone.raw_packet_cache = self.raw_packet_cache
+        clone.raw_packet_cache_fields = self.copy_fields_dict(
+            self.raw_packet_cache_fields
+        )
         clone.post_transforms = self.post_transforms[:]
         clone.__dict__["payload"] = self.payload.copy()
         clone.payload.add_underlayer(clone)
@@ -194,6 +196,7 @@ class Packet(BasePacket):
             self.fields[attr] = any2i(self, val)
             self.explicit = 0
             self.raw_packet_cache = None
+            self.raw_packet_cache_fields = None
         elif attr == "payload":
             self.remove_payload()
             self.add_payload(val)
@@ -215,6 +218,7 @@ class Packet(BasePacket):
             del(self.fields[attr])
             self.explicit = 0 # in case a default value must be explicited
             self.raw_packet_cache = None
+            self.raw_packet_cache_fields = None
         elif self.default_fields.has_key(attr):
             pass
         elif attr == "payload":
@@ -295,9 +299,22 @@ class Packet(BasePacket):
         return True
     def __len__(self):
         return len(self.__str__())
+    def copy_field_value(self, fieldname, value):
+        return self.get_field(fieldname).do_copy(value)
+    def copy_fields_dict(self, fields):
+        if fields is None:
+            return None
+        return dict([fname, self.copy_field_value(fname, fval)]
+                    for fname, fval in fields.iteritems())
     def self_build(self, field_pos_list=None):
         if self.raw_packet_cache is not None:
-            return self.raw_packet_cache
+            for fname, fval in self.raw_packet_cache_fields.iteritems():
+                if self.getfieldval(fname) != fval:
+                    self.raw_packet_cache = None
+                    self.raw_packet_cache_fields = None
+                    break
+            if self.raw_packet_cache is not None:
+                return self.raw_packet_cache
         p=""
         for f in self.fields_desc:
             val = self.getfieldval(f.name)
@@ -558,9 +575,14 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
         flist = self.fields_desc[:]
         flist.reverse()
         raw = s
+        self.raw_packet_cache_fields = {}
         while s and flist:
             f = flist.pop()
-            s,fval = f.getfield(self, s)
+            s, fval = f.getfield(self, s)
+            # We need to track fields with mutable values to discard
+            # .raw_packet_cache when needed.
+            if f.islist or f.holds_packets:
+                self.raw_packet_cache_fields[f.name] = f.do_copy(fval)
             self.fields[f.name] = fval
         assert(raw.endswith(s))
         if s:
@@ -630,14 +652,18 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
         pkt = self.__class__()
         pkt.explicit = 1
         pkt.fields = kargs
+        pkt.default_fields = self.copy_fields_dict(self.default_fields)
         pkt.time = self.time
         pkt.underlayer = self.underlayer
         pkt.overload_fields = self.overload_fields.copy()
         pkt.post_transforms = self.post_transforms
+        pkt.raw_packet_cache = self.raw_packet_cache
+        pkt.raw_packet_cache_fields = self.copy_fields_dict(
+            self.raw_packet_cache_fields
+        )
         if payload is not None:
             pkt.add_payload(payload)
         return pkt
-        
 
     def __iter__(self):
         def loop(todo, done, self=self):
@@ -666,7 +692,7 @@ Creates an EPS file describing a packet. If filename is not provided a temporary
                     pkt = self.clone_with(payload=payl, **done2)
                     yield pkt
 
-        if self.explicit:
+        if self.explicit or self.raw_packet_cache is not None:
             todo = []
             done = self.fields
         else:
diff --git a/scapy/utils.py b/scapy/utils.py
index c5ac2520724de2e893b4cc656e71ec463c9d45aa..07b00ab4e877f86c1693e3de390af24632300510 100644
--- a/scapy/utils.py
+++ b/scapy/utils.py
@@ -646,8 +646,9 @@ class RawPcapWriter:
     
 
     def write(self, pkt):
-        """accepts a either a single packet or a list of packets
-        to be written to the dumpfile
+        """accepts either a single packet or a list of packets to be
+        written to the dumpfile
+
         """
         if not self.header_present:
             self._write_header(pkt)
@@ -700,7 +701,7 @@ class PcapWriter(RawPcapWriter):
                 self.linktype = 1
         RawPcapWriter._write_header(self, pkt)
 
-    def _write_packet(self, packet):        
+    def _write_packet(self, packet):
         sec = int(packet.time)
         usec = int(round((packet.time-sec)*1000000))
         s = str(packet)
diff --git a/test/regression.uts b/test/regression.uts
index b1bc365ad37705b6e098d3b8f342f334db4f91d5..d8f9277d0d2191c2be75ace8c13b3cc5485d3137 100644
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -693,15 +693,21 @@ s.show()
 s.show(2)
 
 = DNS packet manipulation
-~ netaccess DNS
-* We have to recalculate IP and UDP length because
-* DNS is not able to reassemble correctly
+~ netaccess IP UDP DNS
 dns_ans.show()
-del(dns_ans[IP].len)
-del(dns_ans[UDP].len)
 dns_ans.show2()
 dns_ans[DNS].an.show()
-DNS in IP(str(dns_ans))
+dns_ans2 = IP(str(dns_ans))
+DNS in dns_ans2
+assert(str(dns_ans2) == str(dns_ans))
+dns_ans2.qd.qname = "www.secdev.org."
+* We need to recalculate these values
+del(dns_ans2[IP].len)
+del(dns_ans2[IP].chksum)
+del(dns_ans2[UDP].len)
+del(dns_ans2[UDP].chksum)
+assert("\x03www\x06secdev\x03org\x00" in str(dns_ans2))
+assert(DNS in IP(str(dns_ans2)))
 
 = Arping
 ~ netaccess
@@ -1053,13 +1059,15 @@ assert(p == q)
 
 = IP assembly and dissection with options
 ~ IP options
-IP(src="9.10.11.12",dst="13.14.15.16",options=IPOption_SDBM(addresses=["1.2.3.4","5.6.7.8"]))/TCP()
-str(_)
+p = IP(src="9.10.11.12",dst="13.14.15.16",options=IPOption_SDBM(addresses=["1.2.3.4","5.6.7.8"]))/TCP()
+str(p)
 assert(_ == 'H\x00\x004\x00\x01\x00\x00@\x06\xa2q\t\n\x0b\x0c\r\x0e\x0f\x10\x95\n\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00_K\x00\x00')
 q=IP(_)
 q
 assert( isinstance(q.options[0],IPOption_SDBM) )
 assert( q[IPOption_SDBM].addresses[1] == "5.6.7.8" )
+p.options[0].addresses[0] = '5.6.7.8'
+assert( IP(str(p)).options[0].addresses[0] == '5.6.7.8' )
 IP(src="9.10.11.12", dst="13.14.15.16", options=[IPOption_NOP(),IPOption_LSRR(routers=["1.2.3.4","5.6.7.8"]),IPOption_Security(transmission_control_code="XYZ")])/TCP()
 str(_)
 assert(_ == 'K\x00\x00@\x00\x01\x00\x00@\x06\xf3\x83\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x83\x0b\x04\x01\x02\x03\x04\x05\x06\x07\x08\x82\x0b\x00\x00\x00\x00\x00\x00XYZ\x00\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00_K\x00\x00')
diff --git a/test/run_tests b/test/run_tests
index 6cb635945f9a31703142d424d8a99a172ae9988c..7df78972b7472d9e5f28168e56851dd29ae1722c 100755
--- a/test/run_tests
+++ b/test/run_tests
@@ -2,7 +2,7 @@
 DIR=$(dirname $0)/..
 if [ "$*" == "" ]
 then
-PYTHONPATH=$DIR exec python ${DIR}/scapy/tools/UTscapy.py -t regression.uts -f html -o /tmp/scapy_regression_test_$(date +%Y%M%d-%H%H%S).html
+PYTHONPATH=$DIR exec python ${DIR}/scapy/tools/UTscapy.py -t regression.uts -f html -l -o /tmp/scapy_regression_test_$(date +%Y%m%d-%H%M%S).html
 else
 PYTHONPATH=$DIR exec python ${DIR}/scapy/tools/UTscapy.py "$@"
 fi