diff --git a/simulator/extctrl2014.py b/simulator/extctrl2014.py
index 4ed94e443b5b56bd5736ba65350565e1515b0c01..67af2c59b159d1adbd1e5f921f52ee2468e2eadc 100644
--- a/simulator/extctrl2014.py
+++ b/simulator/extctrl2014.py
@@ -32,6 +32,8 @@ import threading
 #   +
 #
 
+ETHERTYPE = 'EX'
+
 flag_MASK =           0x07
 flag_LAST_FRAG =      0x01
 flag_NEED_ACK =       0x02
@@ -130,7 +132,7 @@ class Fragmenter(Encoder):
             fragment = Encoder()
             fragment.write(self.destination)
             fragment.write('\x00\x00\x00\x00\x00\x00')
-            fragment.write('EX')
+            fragment.write(ETHERTYPE)
             if len(remaining) == 0:
                 fragment.encode_byte(self.flags | flag_LAST_FRAG)
             else:
@@ -156,7 +158,7 @@ class Packet:
         self.destination = buf.read(6)
         self.source = buf.read(6)
         self.eth_type = buf.read(2)
-        if self.eth_type == 'EX':
+        if self.eth_type == ETHERTYPE:
             flags = buf.decode_byte()
             self.flags = flags & flag_MASK
             self.kind = flags & kind_MASK
@@ -186,22 +188,50 @@ class Packet:
         self.frag_num = other.frag_num
         self.data += other.data
         return self
-        
+
     def __repr__(self):
-        return "Packet(%s %s %d index=%x flags=%x kind=%x data='%s'" % (
-            ":".join(map(lambda b: "%02.2x" % ord(b), self.destination)),
-            ":".join(map(lambda b: "%02.2x" % ord(b), self.source)),
+        macaddr2str = lambda b: ":".join(["%02.2x" % ord(byte) for byte in b])
+
+        if self.eth_type != ETHERTYPE:
+            int_ethertype = ((ord(self.eth_type[0]) << 8) |
+                             ord(self.eth_type[1]))
+            return "Packet(%s %s 0x%x)" % (
+                macaddr2str(self.destination),
+                macaddr2str(self.source),
+                int_ethertype,
+            )
+
+        flagify = lambda strlist: '(%s)' % ' | '.join(strlist)
+
+        list_flags = []
+        if self.flags & flag_LAST_FRAG:
+            list_flags.append('LAST_FRAG')
+        if self.flags & flag_NEED_ACK:
+            list_flags.append('NEED_ACK')
+        if self.flags & flag_IS_ACK:
+            list_flags.append('IS_ACK')
+
+        list_kind = []
+        if self.kind & kind_INIT:
+            list_kind.append('INIT')
+        if self.kind & kind_DATA:
+            list_kind.append('DATA')
+
+        return "Packet(%s %s channel=%d cookie=0x%x index=0x%x flags=%s kind=%s data='%s'" % (
+            macaddr2str(self.destination),
+            macaddr2str(self.source),
             self.channel,
+            self.cookie,
             self.index,
-            self.flags,
-            self.kind,
+            flagify(list_flags),
+            flagify(list_kind),
             "".join(map(lambda b: "\\x%02.2x" % ord(b), self.data)),
        )
 
 class ExtCtrl(object):
 
     def __init__(self, ethernet, channel, controller=None, robot=None,
-                 max_retries=1000, max_length=1480):
+                 max_retries=1000, max_length=1480, packetdebug=False):
         if len(filter(None, [ robot, controller])) != 1:
             raise Exception('Either robot(%s) or controller(%s) '
                             'should be defined' %
@@ -214,11 +244,13 @@ class ExtCtrl(object):
         self.robot = robot
         self.max_retries = max_retries
         self.max_length = max_length
+        self.packetdebug=packetdebug
         self.read_data = list()
         self.cond = threading.Condition()
         self.local_index = random.randint(1,2**32-1)
         self.remote_index = None
-        self.cookie = None
+        self.cookie_remote_index = None
+        self.cookie_local_index = None
         self.ack = None
         t = threading.Thread(target=self.recv_loop)
         t.daemon = True
@@ -228,6 +260,12 @@ class ExtCtrl(object):
         elif self.robot:
             self.await_INIT()
 
+    @property
+    def cookie(self):
+        if self.cookie_remote_index is None:
+            return 0
+        return self.cookie_local_index ^ self.cookie_remote_index
+
     def next_index(self):
         self.local_index = max(1, (self.local_index + 1) & 0xffffffff)
 
@@ -236,15 +274,28 @@ class ExtCtrl(object):
         data = None
         while True:
             fragment = Packet(self.ethernet.recv(2000))
+            if self.packetdebug:
+                print "Got", fragment
 
             # Sanity check fragment
-            if fragment.eth_type != 'EX':
+            if fragment.eth_type != ETHERTYPE:
+                if self.packetdebug:
+                    print "Bad eth"
                 continue
             if fragment.source != self.other:
+                if self.packetdebug:
+                    print "Bad source"
                 continue
             if fragment.channel != self.channel:
+                if self.packetdebug:
+                    print "Bad channel"
                 continue
             if fragment.cookie != 0 and fragment.cookie != self.cookie:
+                if self.packetdebug:
+                    print "Bad cookie local=%x (seed_local=%x, seed_remote=%x) remote=%x" % (
+                        self.cookie, self.cookie_local_index,
+                        self.cookie_remote_index, fragment.cookie
+                    )
                 continue
 
             # Join fragments
@@ -281,7 +332,8 @@ class ExtCtrl(object):
                         decoder = Decoder(packet.data)
                         with self.cond:
                             self.remote_index = decoder.decode_uint32()
-                            self.cookie = self.remote_index ^ self.local_index
+                            self.cookie_remote_index = self.remote_index
+                            self.cookie_local_index = self.local_index
                             self.cond.notify_all()
             elif packet.kind == kind_INIT:
                 remote_index = packet.index
@@ -289,7 +341,8 @@ class ExtCtrl(object):
                     # Save 
                     with self.cond:
                         self.remote_index = remote_index
-                        self.cookie = self.remote_index ^ self.local_index
+                        self.cookie_remote_index = self.remote_index
+                        self.cookie_local_index = self.local_index
                         self.cond.notify_all()                        
                 if remote_index == self.remote_index:
                     # ACK first INIT or its resends
diff --git a/simulator/robot.py b/simulator/robot.py
index 3300ffc336cccc43250e597b95f67be83fe61312..20912d548f6c67fa4f27e8187adc5285bca3e58a 100755
--- a/simulator/robot.py
+++ b/simulator/robot.py
@@ -107,6 +107,9 @@ if __name__ == '__main__':
     optParser.add_argument('-v', '--verbose',
                            action='store_true',
                            help='be verbose')
+    optParser.add_argument('--packetdebug',
+                           action='store_true',
+                           help='Print incoming packets')
 
     options = optParser.parse_args(sys.argv[1:])
 
@@ -116,7 +119,8 @@ if __name__ == '__main__':
                        recv_loss=options.recv_loss)
     extctrl = extctrl2014.ExtCtrl(ethernet=eth,
                                   channel=options.channel,
-                                  controller=options.connect)
+                                  controller=options.connect,
+                                  packetdebug=options.packetdebug)
     encoder = labcomm2014.Encoder(extctrl.writer())
     decoder = labcomm2014.Decoder(extctrl.reader())
     print encoder, decoder