]> err.no Git - linux-2.6/blobdiff - net/sctp/sm_make_chunk.c
the scheduled ieee80211 softmac removal
[linux-2.6] / net / sctp / sm_make_chunk.c
index 46f54188f00a5e5c3828283ea61549aea8d17948..e45be4e3f80d733c8f3eb27773651ad1a4d44add 100644 (file)
@@ -1,22 +1,22 @@
-/* SCTP kernel reference Implementation
+/* SCTP kernel implementation
  * (C) Copyright IBM Corp. 2001, 2004
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
  * Copyright (c) 2001-2002 Intel Corp.
  *
- * This file is part of the SCTP kernel reference Implementation
+ * This file is part of the SCTP kernel implementation
  *
  * These functions work with the state functions in sctp_sm_statefuns.c
  * to implement the state operations.  These functions implement the
  * steps which require modifying existing data structures.
  *
- * The SCTP reference implementation is free software;
+ * This SCTP implementation is free software;
  * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
  *
- * The SCTP reference implementation is distributed in the hope that it
+ * This SCTP implementation is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -1836,6 +1836,39 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
        return 0;
 }
 
+static int sctp_verify_ext_param(union sctp_params param)
+{
+       __u16 num_ext = ntohs(param.p->length) - sizeof(sctp_paramhdr_t);
+       int have_auth = 0;
+       int have_asconf = 0;
+       int i;
+
+       for (i = 0; i < num_ext; i++) {
+               switch (param.ext->chunks[i]) {
+                   case SCTP_CID_AUTH:
+                           have_auth = 1;
+                           break;
+                   case SCTP_CID_ASCONF:
+                   case SCTP_CID_ASCONF_ACK:
+                           have_asconf = 1;
+                           break;
+               }
+       }
+
+       /* ADD-IP Security: The draft requires us to ABORT or ignore the
+        * INIT/INIT-ACK if ADD-IP is listed, but AUTH is not.  Do this
+        * only if ADD-IP is turned on and we are not backward-compatible
+        * mode.
+        */
+       if (sctp_addip_noauth)
+               return 1;
+
+       if (sctp_addip_enable && !have_auth && have_asconf)
+               return 0;
+
+       return 1;
+}
+
 static void sctp_process_ext_param(struct sctp_association *asoc,
                                    union sctp_params param)
 {
@@ -1966,7 +1999,11 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
        case SCTP_PARAM_UNRECOGNIZED_PARAMETERS:
        case SCTP_PARAM_ECN_CAPABLE:
        case SCTP_PARAM_ADAPTATION_LAYER_IND:
+               break;
+
        case SCTP_PARAM_SUPPORTED_EXT:
+               if (!sctp_verify_ext_param(param))
+                       return SCTP_IERROR_ABORT;
                break;
 
        case SCTP_PARAM_SET_PRIMARY:
@@ -2019,7 +2056,7 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
                break;
 
        case SCTP_PARAM_HMAC_ALGO:
-               if (!sctp_auth_enable)
+               if (sctp_auth_enable)
                        break;
                /* Fall Through */
 fallthrough:
@@ -2139,10 +2176,11 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
                                        !asoc->peer.peer_hmacs))
                asoc->peer.auth_capable = 0;
 
-
-       /* If the peer claims support for ADD-IP without support
-        * for AUTH, disable support for ADD-IP.
-        * Do this only if backward compatible mode is turned off.
+       /* In a non-backward compatible mode, if the peer claims
+        * support for ADD-IP but not AUTH,  the ADD-IP spec states
+        * that we MUST ABORT the association. Section 6.  The section
+        * also give us an option to silently ignore the packet, which
+        * is what we'll do here.
         */
        if (!sctp_addip_noauth &&
             (asoc->peer.asconf_capable && !asoc->peer.auth_capable)) {
@@ -2150,6 +2188,7 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
                                                  SCTP_PARAM_DEL_IP |
                                                  SCTP_PARAM_SET_PRIMARY);
                asoc->peer.asconf_capable = 0;
+               goto clean_up;
        }
 
        /* Walk list of transports, removing transports in the UNKNOWN state. */
@@ -3185,6 +3224,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
        }
 
        /* Free the cached last sent asconf chunk. */
+       list_del_init(&asconf->transmitted_list);
        sctp_chunk_free(asconf);
        asoc->addip_last_asconf = NULL;