static char sccsid[] = "@(#)if.c       8.3 (Berkeley) 4/28/95";
 */
 static const char rcsid[] =
-       "$Id: if.c,v 1.6 2005/01/25 00:10:05 lindak Exp $";
+       "$Id: if.c,v 1.6.40.1 2006/01/10 05:26:27 lindak Exp $";
 #endif /* not lint */
 
 #include <sys/types.h>
                                memcpy(&mask, rti_info[RTAX_NETMASK], ((struct sockaddr_in *)rti_info[RTAX_NETMASK])->sin_len);
                                
                                printf("%-13.13s ", netname(sin->sin_addr.s_addr & mask.sin_addr.s_addr,
-                                   mask.sin_addr.s_addr));
+                                   ntohl(mask.sin_addr.s_addr)));
 
                                printf("%-15.15s ",
                                    routename(sin->sin_addr.s_addr));
 
        /* reject if the size is toooo big */
        if (ntohl(isakmp.len) > 0xffff) {
                plog(LLV_ERROR, LOCATION, NULL,
-                       "the length of the isakmp header is too big.\n");
+                       "the length in the isakmp header is too big.\n");
                if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
                            0, (struct sockaddr *)&remote, &remote_len)) < 0) {
                        plog(LLV_ERROR, LOCATION, NULL,
                        "failed to receive isakmp packet\n");
                goto end;
        }
+
+
+       /* check isakmp header length */
+       if (len < sizeof(temp_buffer)) {
+               plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
+                       "packet shorter than isakmp header size.\n");
+               /* dummy receive */
+               if ((len = recvfrom(so_isakmp, (char *)temp_buffer, sizeof(temp_buffer),
+                       0, (struct sockaddr *)&remote, &remote_len)) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "failed to receive isakmp packet\n");
+               }
+               goto end;
+       }
+
+       /* reject if the size is toooo big */
+       if (ntohl(isakmp->len) > 0xffff) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                       "the length in the isakmp header is too big.\n");
+               if ((len = recvfrom(so_isakmp, (char *)temp_buffer, sizeof(temp_buffer),
+                       0, (struct sockaddr *)&remote, &remote_len)) < 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                               "failed to receive isakmp packet\n");
+               }
+               goto end;
+       }
        
        /* remove the four bytes of zeros on nat traversal port */
        if (*(u_long*)temp_buffer != 0L)
                /*
                 * This is a UDP encapsulated IPSec packet,
                 * we should drop it.
-                *
-                * TBD: Need a way to read the packet.
                 * The kernel intercepts these packets on Mac OS X
-                * but not all kernels will handle this the same way.
+                * so we should not get here.
                 */
-               goto end;
-       }
-
-       /* check isakmp header length */
-       if (len < sizeof(temp_buffer)) {
                plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
-                       "packet shorter than isakmp header size.\n");
+                       "invalid packet - expected non-ESP marker.\n");
                /* dummy receive */
                if ((len = recvfrom(so_isakmp, (char *)temp_buffer, sizeof(temp_buffer),
                            0, (struct sockaddr *)&remote, &remote_len)) < 0) {
 
        natt_select_type(iph1);
        
        /* payload existency check */
-       /* XXX to be checked each authentication method. */
+       if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
+               plog(LLV_ERROR, LOCATION, iph1->remote,
+                       "required payloads missing from isakmp message.\n");
+               goto end;
+       }
 
        /* verify identifier */
        if (ipsecdoi_checkid1(iph1) != 0) {
 
 #ifdef IKE_NAT_T
        if (natd_type) {
-               if (iph1->local_natd)
-                       p = set_isakmp_payload(p, iph1->local_natd, natd_type);
-               if (iph1->remote_natd)
-                       p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
+               if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
+                       if (iph1->local_natd)
+                               p = set_isakmp_payload(p, iph1->local_natd, natd_type);
+                       if (iph1->remote_natd)
+                               p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
+               } else {
+                       if (iph1->remote_natd)
+                               p = set_isakmp_payload(p, iph1->remote_natd, natd_type);
+                       if (iph1->local_natd)
+                               p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
+               }
        }
 #endif
 
        }
 
        /* payload existency check */
-       /* XXX to be checked each authentication method. */
+       if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
+               plog(LLV_ERROR, LOCATION, iph1->remote,
+                       "required payloads missing from isakmp message.\n");
+               goto end;
+       }
 
        /* verify identifier */
        if (ipsecdoi_checkid1(iph1) != 0) {
 #ifdef IKE_NAT_T
                if (nattvid) {
                        p = set_isakmp_payload(p, nattvid, iph1->natd_payload_type);
-                       if (iph1->local_natd)
-                               p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
-                       if (iph1->remote_natd)
-                               p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
+                       if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
+                               if (iph1->local_natd)
+                                       p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
+                               if (iph1->remote_natd)
+                                       p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
+                       } else {
+                               if (iph1->remote_natd)
+                                       p = set_isakmp_payload(p, iph1->remote_natd, iph1->natd_payload_type);
+                               if (iph1->local_natd)
+                                       p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
+                       }
                }
 #endif
                break;
 #ifdef IKE_NAT_T
        if (nattvid) {
                p = set_isakmp_payload(p, nattvid, iph1->natd_payload_type);
-               if (iph1->local_natd)
-                       p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
-               if (iph1->remote_natd)
-                       p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
+               if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
+                       if (iph1->local_natd)
+                               p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
+                       if (iph1->remote_natd)
+                               p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
+               } else {
+                       if (iph1->remote_natd)
+                               p = set_isakmp_payload(p, iph1->remote_natd, iph1->natd_payload_type);
+                       if (iph1->local_natd)
+                               p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
+               }               
        }
 #endif
 
 
 
 #ifdef IKE_NAT_T
        if (natd_type) {
-               if (iph1->local_natd)
-                       p = set_isakmp_payload(p, iph1->local_natd, natd_type);
-               if (iph1->remote_natd)
-                       p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
+               if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
+                       if (iph1->local_natd)
+                               p = set_isakmp_payload(p, iph1->local_natd, natd_type);
+                       if (iph1->remote_natd)
+                               p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
+               } else {
+                       if (iph1->remote_natd)
+                               p = set_isakmp_payload(p, iph1->remote_natd, natd_type);
+                       if (iph1->local_natd)
+                               p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
+               }
        }
 #endif
        error = 0;
 
 
        /* SKEYID */
        switch(iph1->approval->authmethod) {
-       case OAKLEY_ATTR_AUTH_METHOD_PSKEY:     
-               if (iph1->nonce_p == NULL) {
-                       plog(LLV_ERROR, LOCATION, NULL,
-                               "no nonce payload received from peer.\n");
-                       goto end;
-               }
-        /* if we have a preshared key defined, just use it */
-       if (iph1->rmconf->shared_secret) {
+       case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
+                               if (iph1->nonce_p == NULL) {
+                                       plog(LLV_ERROR, LOCATION, NULL,
+                                               "no nonce payload received from peer.\n");
+                                       goto end;
+                               }
+                /* if we have a preshared key defined, just use it */
+                if (iph1->rmconf->shared_secret) {
 
                        switch (iph1->rmconf->secrettype) {
                                case SECRETTYPE_KEY: