Patchwork [PATCHv3,5/6] radius: parse tagged vlan information

login
register
mail settings
Submitter michael-dev@fami-braun.de
Date April 11, 2013, 9:52 a.m.
Message ID <1365673964-17831-6-git-send-email-michael-dev@fami-braun.de>
Download mbox | patch
Permalink /patch/235671/
State Changes Requested
Headers show

Comments

michael-dev@fami-braun.de - April 11, 2013, 9:52 a.m.
From: Michael Braun <michael-dev@fami-braun.de>

Signed-hostap: Michael Braun <michael-dev@fami-braun.de>
---
 src/radius/radius.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 src/radius/radius.h |  1 +
 2 files changed, 43 insertions(+), 3 deletions(-)
Jouni Malinen - May 9, 2013, 10:08 a.m.
On Thu, Apr 11, 2013 at 11:52:43AM +0200, michael-dev@fami-braun.de wrote:
> diff --git a/src/radius/radius.c b/src/radius/radius.c
> @@ -12,6 +12,8 @@
>  #include "utils/wpabuf.h"
>  #include "crypto/md5.h"
>  #include "crypto/crypto.h"
> +#include "ap/hostapd.h"
> +#include "ap/vlan_init.h"
>  #include "radius.h"

This is undesirable. I'd prefer to be able to build the RADIUS
functionality without dependencies on any ap/* files. Is this really
needed? Couldn't the needed definitions be define in radius.h instead to
make this work without such dependencies?

Patch

diff --git a/src/radius/radius.c b/src/radius/radius.c
index d1feec9..93b9541 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -12,6 +12,8 @@ 
 #include "utils/wpabuf.h"
 #include "crypto/md5.h"
 #include "crypto/crypto.h"
+#include "ap/hostapd.h"
+#include "ap/vlan_init.h"
 #include "radius.h"
 
 
@@ -214,6 +216,8 @@  static struct radius_attr_type radius_attrs[] =
 	  RADIUS_ATTR_INT32 },
 	{ RADIUS_ATTR_EVENT_TIMESTAMP, "Event-Timestamp",
 	  RADIUS_ATTR_INT32 },
+	{ RADIUS_ATTR_EGRESS_VLANID, "Egress-VLANID",
+	  RADIUS_ATTR_INT32 },
 	{ RADIUS_ATTR_NAS_PORT_TYPE, "NAS-Port-Type", RADIUS_ATTR_INT32 },
 	{ RADIUS_ATTR_TUNNEL_TYPE, "Tunnel-Type", RADIUS_ATTR_HEXDUMP },
 	{ RADIUS_ATTR_TUNNEL_MEDIUM_TYPE, "Tunnel-Medium-Type",
@@ -1342,8 +1346,10 @@  int radius_msg_get_vlanid(struct radius_msg *msg)
 	const u8 *data;
 	char buf[10];
 	size_t dlen;
+	struct vlan_info ret;
 
 	os_memset(&tunnel, 0, sizeof(tunnel));
+	os_memset(&ret, 0, sizeof(ret));
 
 	for (i = 0; i < msg->attr_used; i++) {
 		attr = radius_get_attr_hdr(msg, i);
@@ -1383,6 +1389,28 @@  int radius_msg_get_vlanid(struct radius_msg *msg)
 			tun->tag_used++;
 			tun->vlanid = atoi(buf);
 			break;
+		case RADIUS_ATTR_EGRESS_VLANID: /* RFC 4675 */
+			if (attr->length != 6)
+				break;
+			int vlan_id = WPA_GET_BE24(data + 1);
+			if (vlan_id <= 0 || vlan_id > MAX_VLAN_ID)
+				break;
+			if (data[0] == 0x31) { /* tagged vlan */
+				#ifdef CONFIG_VLAN_TAGGED
+				int* new_tagged = os_zalloc(sizeof(int) * (ret.num_tagged + 1));
+				if (!new_tagged)
+					break;
+				if (ret.num_tagged > 0)
+					os_memcpy(new_tagged, ret.tagged, sizeof(int) * ret.num_tagged);
+				new_tagged[ret.num_tagged] = vlan_id;
+				os_free(ret.tagged);
+				ret.tagged = new_tagged;
+				ret.num_tagged++;
+				#endif /* CONFIG_VLAN_TAGGED */
+			} else if (data[0] == 0x32) { /* untagged vlan */
+				ret.untagged = vlan_id;
+			}
+			break;
 		}
 	}
 
@@ -1392,12 +1420,23 @@  int radius_msg_get_vlanid(struct radius_msg *msg)
 		    tun->type == RADIUS_TUNNEL_TYPE_VLAN &&
 		    tun->medium_type == RADIUS_TUNNEL_MEDIUM_TYPE_802 &&
 		    tun->vlanid > 0)
-			return tun->vlanid;
+		{
+			ret.untagged = tun->vlanid;
+			break;
+		}
 	}
 
-	return -1;
-}
+	if (ret.untagged < 0 || ret.untagged > MAX_VLAN_ID)
+		ret.untagged = 0;
+	#ifdef CONFIG_VLAN_TAGGED
+	vlan_cleanup(&ret);
+	#endif
 
+	if (!ret.untagged && !ret.tagged)
+		return -1;
+
+	return vlan_get_id(&ret);
+}
 
 /**
  * radius_msg_get_tunnel_password - Parse RADIUS attribute Tunnel-Password
diff --git a/src/radius/radius.h b/src/radius/radius.h
index 2031054..e0ebe6d 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -79,6 +79,7 @@  enum { RADIUS_ATTR_USER_NAME = 1,
        RADIUS_ATTR_ACCT_INPUT_GIGAWORDS = 52,
        RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS = 53,
        RADIUS_ATTR_EVENT_TIMESTAMP = 55,
+       RADIUS_ATTR_EGRESS_VLANID = 56,
        RADIUS_ATTR_NAS_PORT_TYPE = 61,
        RADIUS_ATTR_TUNNEL_TYPE = 64,
        RADIUS_ATTR_TUNNEL_MEDIUM_TYPE = 65,