--- ./src/modules/rlm_wimax/rlm_wimax.orig	2010-02-03 09:52:09.000000000 -0600
+++ ./src/modules/rlm_wimax/rlm_wimax.c	2010-02-03 10:02:08.000000000 -0600
@@ -485,58 +485,112 @@
 		}
 	}
 
-	/*
-	 *	Generate MN-FA = H(FA-RK, "MN FA" | FA-IP | MN-NAI)
-	 */
-	ip = pairfind(request->reply->vps, 1901);
-	if (fa_rk && ip && mn_nai) {
-		HMAC_CTX_init(&hmac);
-		HMAC_Init_ex(&hmac, fa_rk->vp_octets, fa_rk->length,
-			     EVP_sha1(), NULL);
-		
-		HMAC_Update(&hmac, (const uint8_t *) "MN FA", 5);
-		HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipaddr, 4);
-		HMAC_Update(&hmac, (const uint8_t *) &mn_nai->vp_strvalue, mn_nai->length);
-
-		HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len);
-
-		vp = radius_paircreate(request, &request->reply->vps,
-				       1902, PW_TYPE_OCTETS);
-		if (!vp) {
-			RDEBUG("WARNING: Failed creating WiMAX-MN-FA");
-		} else {
-			memcpy(vp->vp_octets, &mip_rk_1[0], rk1_len);
-			vp->length = rk1_len;
-		}
-	}
+        /*
+         *      Generate RRQ-MN-HA Key if requested.
+         *
+         *      This is generated using the same method as the MN-HA keys above,
+         *      however uses the RRQ-HA-IP instead of the actual HA-IP. This is used
+         *      in cases where the MN does not know the IP address of the HA during
+         *      network entry.
+         *
+         *      Only valid with CMIP
+         */
+
+        /*
+         *      Look for WiMAX-RRQ-HA-IP
+         */
+        ip = pairfind(request->packet->vps, WIMAX2ATTR(18));
+        if (ip) {
+                RDEBUG("WiMAX-RRQ-HA-IP found. Calculating RRQ-MN-HA key");
+
+                /*
+                 *      If not valid HA-IP address stop now...
+                 */
+
+                /*
+                 *      WiMAX-RRQ-HA-IP can contain either an IPv4 address, an IPv6
+                 *      address, or the ALL-ZERO-ONE-ADDR. It is assumed by the WMF that
+                 *      all networks will be homogeneous.
+                 */
+
+                /*
+                 *      RRQ-MN-HA =
+                 *         For CMIP4:
+                 *         H(MIP-RK, "CMIP4 MN HA" | RRQ-HA-IP (IPv4) | MN-NAI);
+                 *         - or -
+                 *         For CMIP6:
+                 *         H(MIP-RK, "CMIP6 MN HA" | RRQ-HA-IP (IPv6) | MN-NAI );
+                 */
+                HMAC_CTX_init(&hmac);
+                HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL);
+
+                /*
+                 *      RRQ-HA-IP is an IPv4 address
+                 */
+                if ((ip->type == PW_TYPE_IPADDR) /* && valid IPv4 address */) {
+                        HMAC_Update(&hmac, (const uint8_t *) "CMIP4 MN HA", 11);
+                        HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipaddr, 4);
+                }
+
+                /*
+                 *      RRQ-HA-IP is an IPv6 address
+                 */
+                if ((ip->type == PW_TYPE_IPV6ADDR) /* && valid IPv6 address */) {
+                        HMAC_Update(&hmac, (const uint8_t *) "CMIP6 MN HA", 11);
+                        HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipv6addr, 16);
+                }
+
+                HMAC_Update(&hmac, (const uint8_t *) &mn_nai->vp_strvalue, mn_nai->length);
+                HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len);
+
+                /*
+                 *      Put key into WiMAX-RRQ-MN-HA-Key
+                 */
+                vp = pairfind(request->reply->vps, WIMAX2ATTR(19));
+                if (!vp) {
+                        vp = radius_paircreate(request, &request->reply->vps,
+                                               WIMAX2ATTR(19), PW_TYPE_OCTETS);
+                }
+                if (!vp) {
+                        RDEBUG("WARNING: Failed creating WiMAX-RRQ-MN-HA-Key");
+                } else {
+                        memcpy(vp->vp_octets, &mip_rk_1[0], rk1_len);
+                        vp->length = rk1_len;
+                }
+
+                /*
+                 *      If WiMAX-RRQ-HA-IP exists in request it must also be in
+                 *      the reply. Insert WiMAX-RRQ-HA-IP into reply list as well.
+                 */
+                vp = pairfind(request->reply->vps, WIMAX2ATTR(18));
+                if (!vp) {
+                        vp = radius_paircreate(request, &request->reply->vps,
+                                        WIMAX2ATTR(18), PW_TYPE_COMBO_IP);
+                }
+                if (!vp) {
+                        RDEBUG("WARNING: Failed creating WiMAX-RRQ-HA-IP in reply list");
+                } else {
+                        if (ip->type == PW_TYPE_IPADDR) {
+                                vp->vp_ipaddr = ip->vp_ipaddr; /* IPv4 */
+                                vp->type = PW_TYPE_IPADDR;
+                                vp->length = 4;
+                        }
+                        if (ip->type == PW_TYPE_IPV6ADDR) {
+                                vp->vp_ipv6addr = ip->vp_ipv6addr; /* IPv6 */
+                                vp->type = PW_TYPE_IPV6ADDR;
+                                vp->length = 16;
+                        }
+                }
+        }
 
 	/*
 	 *	Give additional information about requests && responses
 	 *
-	 *	WiMAX-RRQ-MN-HA-SPI
+	 *	WiMAX-HA-RK-Requested
 	 */
-	vp = pairfind(request->packet->vps, WIMAX2ATTR(20));
-	if (vp) {
-		RDEBUG("Client requested MN-HA key: Should use SPI to look up key from storage.");
-		if (!mn_nai) {
-			RDEBUG("WARNING: MN-NAI was not found!");
-		}
-
-		/*
-		 *	WiMAX-RRQ-HA-IP
-		 */
-		if (!pairfind(request->packet->vps, WIMAX2ATTR(18))) {
-			RDEBUG("WARNING: HA-IP was not found!");
-		}
-
-
-		/*
-		 *	WiMAX-HA-RK-Key-Requested
-		 */
-		vp = pairfind(request->packet->vps, WIMAX2ATTR(58));
-		if (vp && (vp->vp_integer == 1)) {
-			RDEBUG("Client requested HA-RK: Should use IP to look it up from storage.");
-		}
+	vp = pairfind(request->packet->vps, WIMAX2ATTR(58));
+	if (vp && (vp->vp_integer == 1)) {
+		RDEBUG("Client requested HA-RK: Should use IP to look it up from storage.");
 	}
 
 	/*
