<rdar://problem/7222658> Sleep Proxy + BTMM: (proxy side) SS wakes on its own 2-5...
authorcheshire@apple.com <cheshire@apple.com@214c2c4a-bf3b-4dcf-9390-e4dd3010487d>
Wed, 23 Sep 2009 03:37:07 +0000 (03:37 +0000)
committercheshire@apple.com <cheshire@apple.com@214c2c4a-bf3b-4dcf-9390-e4dd3010487d>
Wed, 23 Sep 2009 03:37:07 +0000 (03:37 +0000)
Ignore informational IKE packets

git-svn-id: http://svn.macosforge.org/repository/mDNSResponder/trunk@6687 214c2c4a-bf3b-4dcf-9390-e4dd3010487d

mDNSCore/mDNS.c
mDNSCore/mDNSEmbeddedAPI.h

index ef5a604..1d4b5dc 100755 (executable)
@@ -7810,27 +7810,51 @@ mDNSexport void mDNSCoreReceiveRawPacket(mDNS *const m, const mDNSu8 *const p, c
 
                                case 17:        {
                                                        const UDPHeader *const udp = (const UDPHeader *)trans;
-                                                       mDNSu16 len = (mDNSu16)((mDNSu16)trans[4] << 8 | trans[5]);
-                                                       port = udp->dst;
-                                                       wake = mDNStrue;
-
-                                                       // For Back to My Mac UDP port 4500 (IPSEC) packets, we specially ignore NAT keepalive packets
-                                                       if (mDNSSameIPPort(port, IPSECPort)) wake = (len != 9 || end < trans + 9 || trans[8] != 0xFF);
-
-                                                       // For now, because we haven't yet worked out a clean elegant way to do this, we just special-case the
-                                                       // Apple Remote Desktop port number -- we ignore all packets to UDP 3283 (the "Net Assistant" port),
-                                                       // except for Apple Remote Desktop's explicit manual wakeup packet, which looks like this:
-                                                       // UDP header (8 bytes) 13 88 00 6a 41 4e 41 20 (8 bytes) ffffffffffff (6 bytes) 16xMAC (96 bytes) = 118 bytes total
-                                                       if (mDNSSameIPPort(port, ARD)) wake = (len >= 118 && end >= trans+10 && trans[8] == 0x13 && trans[9] == 0x88);
-
-                                                       LogSPS("%s %d-byte UDP from %.4a:%d to %.4a:%d", XX, &v4->src, mDNSVal16(udp->src), &v4->dst, mDNSVal16(port));
+                                                       const mDNSu16 udplen = (mDNSu16)((mDNSu16)trans[4] << 8 | trans[5]);            // Length *including* 8-byte UDP header
+                                                       if (udplen >= sizeof(UDPHeader))
+                                                               {
+                                                               const mDNSu16 datalen = udplen - sizeof(UDPHeader);
+                                                               port = udp->dst;
+                                                               wake = mDNStrue;
+
+                                                               // For Back to My Mac UDP port 4500 (IPSEC) packets, we do some special handling
+                                                               if (mDNSSameIPPort(port, IPSECPort))
+                                                                       {
+                                                                       // Specifically ignore NAT keepalive packets
+                                                                       if (datalen == 1 && end >= trans + 9 && trans[8] == 0xFF) wake = mDNSfalse;
+                                                                       else
+                                                                               {
+                                                                               // Skip over the Non-ESP Marker if present
+                                                                               const mDNSBool NonESP = (end >= trans + 12 && trans[8] == 0 && trans[9] == 0 && trans[10] == 0 && trans[11] == 0);
+                                                                               const IKEHeader *const ike    = (IKEHeader *)(trans + (NonESP ? 12 : 8));
+                                                                               const mDNSu16          ikelen = datalen - (NonESP ? 4 : 0);
+                                                                               if (ikelen >= sizeof(IKEHeader) && end >= ((mDNSu8 *)ike) + sizeof(IKEHeader))
+                                                                                       if ((ike->Version & 0x10) == 0x10)
+                                                                                               {
+                                                                                               // ExchangeType ==  5 means 'Informational' <http://www.ietf.org/rfc/rfc2408.txt>
+                                                                                               // ExchangeType == 34 means 'IKE_SA_INIT'   <http://www.iana.org/assignments/ikev2-parameters>
+                                                                                               if (ike->ExchangeType == 5 || ike->ExchangeType == 34) wake = mDNSfalse;
+                                                                                               LogSPS("%s %d-byte IKE ExchangeType %d", XX, ike->ExchangeType);
+                                                                                               }
+                                                                               }
+                                                                       }
+
+                                                               // For now, because we haven't yet worked out a clean elegant way to do this, we just special-case the
+                                                               // Apple Remote Desktop port number -- we ignore all packets to UDP 3283 (the "Net Assistant" port),
+                                                               // except for Apple Remote Desktop's explicit manual wakeup packet, which looks like this:
+                                                               // UDP header (8 bytes)
+                                                               // Payload: 13 88 00 6a 41 4e 41 20 (8 bytes) ffffffffffff (6 bytes) 16xMAC (96 bytes) = 110 bytes total
+                                                               if (mDNSSameIPPort(port, ARD)) wake = (datalen >= 110 && end >= trans+10 && trans[8] == 0x13 && trans[9] == 0x88);
+
+                                                               LogSPS("%s %d-byte UDP from %.4a:%d to %.4a:%d", XX, &v4->src, mDNSVal16(udp->src), &v4->dst, mDNSVal16(port));
+                                                               }
                                                        }
                                                        break;
 
                                default:        LogSPS("%s %d-byte IP packet unknown protocol %d from %.4a to %.4a", XX, v4->protocol, &v4->src, &v4->dst);
                                                        break;
                                }
-       
+
                        if (wake)
                                {
                                AuthRecord *rr, *r2;
index 0504708..ad0424c 100755 (executable)
@@ -531,6 +531,18 @@ typedef packedstruct
        mDNSu16      checksum;
        } UDPHeader;                    // 8 bytes
 
+typedef packedstruct
+       {
+       mDNSOpaque64 InitiatorCookie;
+       mDNSOpaque64 ResponderCookie;
+       mDNSu8       NextPayload;
+       mDNSu8       Version;
+       mDNSu8       ExchangeType;
+       mDNSu8       Flags;
+       mDNSOpaque32 MessageID;
+       mDNSu32      Length;
+       } IKEHeader;                    // 28 bytes
+
 typedef packedstruct
        {
        mDNSIPPort   src;
@@ -2533,7 +2545,8 @@ struct CompileTimeAssertionChecks_mDNS
        char assertI[(sizeof(IPv6Header    )   ==   40                         ) ? 1 : -1];
        char assertJ[(sizeof(IPv6ND        )   ==   24                         ) ? 1 : -1];
        char assertK[(sizeof(UDPHeader     )   ==    8                         ) ? 1 : -1];
-       char assertL[(sizeof(TCPHeader     )   ==   20                         ) ? 1 : -1];
+       char assertL[(sizeof(IKEHeader     )   ==   28                         ) ? 1 : -1];
+       char assertM[(sizeof(TCPHeader     )   ==   20                         ) ? 1 : -1];
 
        // Check our structures are reasonable sizes. Including overly-large buffers, or embedding
        // other overly-large structures instead of having a pointer to them, can inadvertently