K2.6 patches and update.
[tomato.git] / release / src-rt / wl / eapd / nas_eap.c
blobf1487a728c01ca6e3de146901d472b7ed187f6d3
1 /*
2 * Application-specific portion of EAPD
3 * (NAS)
5 * Copyright (C) 2010, Broadcom Corporation
6 * All Rights Reserved.
7 *
8 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
9 * the contents of this file may not be disclosed to third parties, copied
10 * or duplicated in any form, in whole or in part, without the prior
11 * written permission of Broadcom Corporation.
13 * $Id: nas_eap.c 241391 2011-02-18 03:35:48Z stakita $
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <net/if.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
25 #include <typedefs.h>
26 #include <bcmutils.h>
27 #include <proto/ethernet.h>
28 #include <proto/eapol.h>
29 #include <proto/eap.h>
30 #include <bcmendian.h>
31 #include <wlutils.h>
32 #include <eapd.h>
33 #include <shutils.h>
34 #include <UdpLib.h>
35 #include <nas.h>
36 #include <security_ipc.h>
37 #include <bcmwpa.h>
39 /* mapping from WPA_CIPHER_XXXX to wsec */
40 #define NAS_APP_WPA_CIPHER2WSEC(cipher) ((cipher) == WPA_CIPHER_WEP_40 ? WEP_ENABLED : \
41 (cipher) == WPA_CIPHER_WEP_104 ? WEP_ENABLED : \
42 (cipher) == WPA_CIPHER_TKIP ? TKIP_ENABLED : \
43 (cipher) == WPA_CIPHER_AES_CCM ? AES_ENABLED : \
46 static uint32
47 nas_app_wpa_akm2auth(uint32 akm)
49 switch (akm) {
50 case RSN_AKM_PSK:
51 return WPA_AUTH_PSK;
52 case RSN_AKM_UNSPECIFIED:
53 return WPA_AUTH_UNSPECIFIED;
54 case RSN_AKM_NONE:
55 default:
56 return WPA_AUTH_NONE;
60 #ifdef BCMWPA2
61 static uint32
62 nas_app_wpa2_akm2auth(uint32 akm)
64 switch (akm) {
65 case RSN_AKM_PSK:
66 return WPA2_AUTH_PSK;
67 case RSN_AKM_UNSPECIFIED:
68 return WPA2_AUTH_UNSPECIFIED;
69 case RSN_AKM_NONE:
70 default:
71 return WPA_AUTH_NONE;
74 #endif /* BCMWPA2 */
76 static int
77 nas_app_wpa_auth2mode(int auth)
79 switch (auth) {
80 case WPA_AUTH_PSK:
81 return WPA_PSK;
82 case WPA_AUTH_UNSPECIFIED:
83 return WPA;
84 #ifdef BCMWPA2
85 case WPA2_AUTH_PSK:
86 return WPA2_PSK;
87 case WPA2_AUTH_UNSPECIFIED:
88 return WPA2;
89 #endif /* BCMWPA2 */
90 case WPA_AUTH_DISABLED:
91 default:
92 return RADIUS;
96 static bool
97 nas_app_is_wpa_ie(uint8 *ie, uint8 **tlvs, uint *tlvs_len)
99 /* If the contents match the WPA_OUI and type=1 */
100 if ((ie[TLV_LEN_OFF] > (WPA_OUI_LEN+1)) &&
101 !bcmp(&ie[TLV_BODY_OFF], WPA_OUI "\x01", WPA_OUI_LEN + 1)) {
102 return TRUE;
105 /* point to the next ie */
106 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
107 /* calculate the length of the rest of the buffer */
108 *tlvs_len -= (int)(ie - *tlvs);
109 /* update the pointer to the start of the buffer */
110 *tlvs = ie;
112 return FALSE;
115 static bool
116 nas_app_is_wps_ie(uint8 *ie, uint8 **tlvs, uint *tlvs_len)
118 /* If the contents match the WPA_OUI and type=4 */
119 if ((ie[TLV_LEN_OFF] > (WPA_OUI_LEN+1)) &&
120 !bcmp(&ie[TLV_BODY_OFF], WPA_OUI "\x04", WPA_OUI_LEN + 1)) {
121 return TRUE;
124 /* point to the next ie */
125 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
126 /* calculate the length of the rest of the buffer */
127 *tlvs_len -= (int)(ie - *tlvs);
128 /* update the pointer to the start of the buffer */
129 *tlvs = ie;
131 return FALSE;
134 static bcm_tlv_t *
135 nas_app_parse_tlvs(void *buf, int buflen, uint key)
137 bcm_tlv_t *elt;
138 int totlen;
140 elt = (bcm_tlv_t*)buf;
141 totlen = buflen;
143 /* find tagged parameter */
144 while (totlen >= 2) {
145 int len = elt->len;
147 /* validate remaining totlen */
148 if ((elt->id == key) && (totlen >= (len + 2)))
149 return (elt);
151 elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
152 totlen -= (len + 2);
155 return NULL;
158 static wpa_ie_fixed_t *
159 nas_app_find_wpaie(uint8 *parse, uint len)
161 bcm_tlv_t *ie;
163 while ((ie = nas_app_parse_tlvs(parse, len, DOT11_MNG_WPA_ID))) {
164 if (nas_app_is_wpa_ie((uint8*)ie, &parse, &len)) {
165 return (wpa_ie_fixed_t *)ie;
168 return NULL;
171 static wpa_ie_fixed_t *
172 nas_app_find_wpsie(uint8 *parse, uint len)
174 bcm_tlv_t *ie;
176 while ((ie = nas_app_parse_tlvs(parse, len, DOT11_MNG_WPA_ID))) {
177 if (nas_app_is_wps_ie((uint8*)ie, &parse, &len)) {
178 return (wpa_ie_fixed_t *)ie;
181 return NULL;
184 /* decode WPA IE to retrieve supplicant wsec, auth mode, and pmk cached */
185 /* pmkc - 0:no pmkid in ie, -1:pmkid not found, 1:pmkid found */
186 static int
187 nas_app_parse_ie(uint8 *ie, int ie_len, uint32 *wsec, uint32 *mode)
189 int len;
190 wpa_suite_mcast_t *mcast = NULL;
191 wpa_suite_ucast_t *ucast = NULL;
192 wpa_suite_auth_key_mgmt_t *mgmt = NULL;
193 uint8 *oui;
195 uint16 count;
196 uint32 m = 0;
197 uint32 (*akm2auth)(uint32 akm) = NULL;
198 wpa_ie_fixed_t *wpaie = NULL;
199 uint8 *parse = ie;
200 int parse_len = ie_len;
203 if (nas_app_find_wpsie(parse, parse_len))
204 return -1;
206 /* Search WPA IE */
207 wpaie = nas_app_find_wpaie(parse, parse_len);
208 #ifdef BCMWPA2
209 /* Search RSN IE */
210 if (!wpaie)
211 wpaie = (wpa_ie_fixed_t *)nas_app_parse_tlvs(ie, ie_len, DOT11_MNG_RSN_ID);
212 #endif /* BCMWPA2 */
214 /* No WPA or RSN IE */
215 if (!wpaie)
216 return -1;
218 /* type specific header processing */
219 switch (wpaie->tag) {
220 #ifdef BCMWPA2
221 case DOT11_MNG_RSN_ID: {
222 wpa_rsn_ie_fixed_t *rsnie = (wpa_rsn_ie_fixed_t *)wpaie;
223 if (rsnie->length < WPA_RSN_IE_TAG_FIXED_LEN) {
224 EAPD_ERROR("invalid RSN IE header\n");
225 return -1;
227 if (ltoh16_ua((uint8 *)&rsnie->version) != WPA2_VERSION) {
228 EAPD_ERROR("unsupported RSN IE version\n");
229 return -1;
231 mcast = (wpa_suite_mcast_t *)(rsnie + 1);
232 len = ie_len - WPA_RSN_IE_FIXED_LEN;
233 oui = (uint8*)WPA2_OUI;
234 akm2auth = nas_app_wpa2_akm2auth;
235 break;
237 #endif /* BCMWPA2 */
238 case DOT11_MNG_WPA_ID: {
239 if (wpaie->length < WPA_IE_TAG_FIXED_LEN ||
240 bcmp(wpaie->oui, WPA_OUI "\x01", WPA_IE_OUITYPE_LEN)) {
241 EAPD_ERROR("invalid WPA IE header\n");
242 return -1;
244 if (ltoh16_ua((uint8 *)&wpaie->version) != WPA_VERSION) {
245 EAPD_ERROR("unsupported WPA IE version\n");
246 return -1;
248 mcast = (wpa_suite_mcast_t *)(wpaie + 1);
249 len = ie_len - WPA_IE_FIXED_LEN;
250 oui = (uint8*)WPA_OUI;
251 akm2auth = nas_app_wpa_akm2auth;
252 break;
254 default:
255 EAPD_ERROR("unsupported IE type\n");
256 return -1;
260 /* init return values - no mcast cipher and no ucast cipher */
261 if (wsec)
262 *wsec = 0;
263 if (mode)
264 *mode = 0;
266 /* Check for multicast suite */
267 if (len >= WPA_SUITE_LEN) {
268 if (!bcmp(mcast->oui, oui, DOT11_OUI_LEN)) {
269 if (wsec)
270 *wsec |= NAS_APP_WPA_CIPHER2WSEC(mcast->type);
272 len -= WPA_SUITE_LEN;
274 /* Check for unicast suite(s) */
275 if (len >= WPA_IE_SUITE_COUNT_LEN) {
276 ucast = (wpa_suite_ucast_t *)&mcast[1];
277 count = ltoh16_ua((uint8 *)&ucast->count);
278 len -= WPA_IE_SUITE_COUNT_LEN;
279 if (count != 1) {
280 EAPD_ERROR("# of unicast cipher suites %d\n", count);
281 return -1;
283 if (!bcmp(ucast->list[0].oui, oui, DOT11_OUI_LEN)) {
284 if (wsec)
285 *wsec |= NAS_APP_WPA_CIPHER2WSEC(ucast->list[0].type);
287 len -= WPA_SUITE_LEN;
289 /* Check for auth key management suite(s) */
290 if (len >= WPA_IE_SUITE_COUNT_LEN) {
291 mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[1];
292 count = ltoh16_ua((uint8 *)&mgmt->count);
293 len -= WPA_IE_SUITE_COUNT_LEN;
294 if (count != 1) {
295 EAPD_ERROR("# of AKM suites %d\n", count);
296 return -1;
298 if (!bcmp(mgmt->list[0].oui, oui, DOT11_OUI_LEN)) {
299 m = nas_app_wpa_auth2mode(akm2auth(mgmt->list[0].type));
300 if (mode)
301 *mode = m;
303 len -= WPA_SUITE_LEN;
305 EAPD_INFO("wsec 0x%x mode 0x%x\n", *wsec, *mode);
307 return 0;
310 /* Receive eapol, preauth message from nas module
312 void
313 nas_app_recv_handler(eapd_wksp_t *nwksp, char *wlifname, eapd_cb_t *from, uint8 *pData,
314 int *pLen)
316 eapol_header_t *eapol = (eapol_header_t*) pData;
317 eap_header_t *eap;
318 struct ether_addr *sta_ea;
319 eapd_sta_t *sta;
320 struct eapd_socket *Socket = NULL;
322 if (!nwksp || !wlifname || !from || !pData) {
323 EAPD_ERROR("Wrong argument...\n");
324 return;
327 if (*pLen < EAPOL_HEADER_LEN)
328 return; /* message too short */
330 /* dispatch message to eapol, preauth and brcmevent */
331 switch (ntohs(eapol->eth.ether_type)) {
332 case ETHER_TYPE_802_1X: /* eapol */
333 case ETHER_TYPE_BRCM: /* brcmevent */
334 Socket = from->brcmSocket;
335 break;
336 #ifdef BCMWPA2
337 case ETHER_TYPE_802_1X_PREAUTH: /* preauth */
338 Socket = &from->preauthSocket;
339 break;
340 #endif
343 /* send message data out. */
344 sta_ea = (struct ether_addr*) eapol->eth.ether_dhost;
345 sta = sta_lookup(nwksp, sta_ea, NULL, wlifname, EAPD_SEARCH_ONLY);
347 /* monitor eapol packet */
348 eap = (eap_header_t *) eapol->body;
349 if ((sta) && (eapol->type == EAP_PACKET) &&
350 (eap->code == EAP_FAILURE || eap->code == EAP_SUCCESS)) {
351 sta_remove(nwksp, sta);
354 if (Socket != NULL) {
355 eapd_message_send(nwksp, Socket, pData, *pLen);
357 else {
358 EAPD_ERROR("Socket is not exist!\n");
360 return;
363 void
364 nas_app_set_eventmask(eapd_app_t *app)
366 memset(app->bitvec, 0, sizeof(app->bitvec));
368 setbit(app->bitvec, WLC_E_EAPOL_MSG);
369 setbit(app->bitvec, WLC_E_LINK);
370 setbit(app->bitvec, WLC_E_ASSOC_IND);
371 setbit(app->bitvec, WLC_E_REASSOC_IND);
372 setbit(app->bitvec, WLC_E_DISASSOC_IND);
373 setbit(app->bitvec, WLC_E_DEAUTH_IND);
374 setbit(app->bitvec, WLC_E_MIC_ERROR);
375 return;
379 nas_app_init(eapd_wksp_t *nwksp)
381 int reuse = 1;
382 eapd_nas_t *nas;
383 eapd_cb_t *cb;
384 #ifdef BCMWPA2
385 eapd_preauth_socket_t *preauthSocket;
386 #endif
387 struct sockaddr_in addr;
390 if (nwksp == NULL)
391 return -1;
393 nas = &nwksp->nas;
394 nas->appSocket = -1;
396 cb = nas->cb;
397 if (cb == NULL) {
398 EAPD_INFO("No any NAS application need to run.\n");
399 return 0;
402 while (cb) {
403 EAPD_INFO("nas: init brcm interface %s \n", cb->ifname);
404 cb->brcmSocket = eapd_add_brcm(nwksp, cb->ifname);
405 if (!cb->brcmSocket)
406 return -1;
407 /* set this brcmSocket have NAS capability */
408 cb->brcmSocket->flag |= EAPD_CAP_NAS;
410 #ifdef BCMWPA2
411 /* open preauth socket */
412 preauthSocket = &cb->preauthSocket;
413 memset(preauthSocket, 0, sizeof(eapd_preauth_socket_t));
414 strcpy(preauthSocket->ifname, cb->ifname);
415 EAPD_INFO("nas: init preauth interface %s \n", cb->ifname);
416 if (eapd_preauth_open(nwksp, preauthSocket) < 0) {
417 EAPD_ERROR("open preauth socket on %s error!!\n", preauthSocket->ifname);
418 preauthSocket->drvSocket = -1;
420 #endif
421 cb = cb->next;
424 /* appSocket for nas */
425 nas->appSocket = socket(AF_INET, SOCK_DGRAM, 0);
426 if (nas->appSocket < 0) {
427 EAPD_ERROR("UDP Open failed.\n");
428 return -1;
430 #if defined(__ECOS)
431 if (setsockopt(nas->appSocket, SOL_SOCKET, SO_REUSEPORT, (char*)&reuse,
432 sizeof(reuse)) < 0) {
433 EAPD_ERROR("UDP setsockopt failed.\n");
434 close(nas->appSocket);
435 nas->appSocket = -1;
436 return -1;
438 #else
439 if (setsockopt(nas->appSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse,
440 sizeof(reuse)) < 0) {
441 EAPD_ERROR("UDP setsockopt failed.\n");
442 close(nas->appSocket);
443 nas->appSocket = -1;
444 return -1;
446 #endif
448 memset(&addr, 0, sizeof(struct sockaddr_in));
449 addr.sin_family = AF_INET;
450 addr.sin_addr.s_addr = INADDR_ANY;
451 addr.sin_port = htons(EAPD_WKSP_NAS_UDP_RPORT);
452 if (bind(nas->appSocket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
453 EAPD_ERROR("UDP Bind failed, close nas appSocket %d\n", nas->appSocket);
454 close(nas->appSocket);
455 nas->appSocket = -1;
456 return -1;
458 EAPD_INFO("NAS appSocket %d opened\n", nas->appSocket);
460 return 0;
464 nas_app_deinit(eapd_wksp_t *nwksp)
466 eapd_nas_t *nas;
467 eapd_cb_t *cb, *tmp_cb;
468 #ifdef BCMWPA2
469 eapd_preauth_socket_t *preauthSocket;
470 #endif
472 if (nwksp == NULL) {
473 EAPD_ERROR("Wrong argument...\n");
474 return -1;
477 nas = &nwksp->nas;
478 cb = nas->cb;
479 while (cb) {
480 /* close brcm drvSocket */
481 if (cb->brcmSocket) {
482 EAPD_INFO("close nas brcmSocket %d\n", cb->brcmSocket->drvSocket);
483 eapd_del_brcm(nwksp, cb->brcmSocket);
486 #ifdef BCMWPA2
487 /* close preauth drvSocket */
488 preauthSocket = &cb->preauthSocket;
489 if (preauthSocket->drvSocket >= 0) {
490 EAPD_INFO("close nas preauthSocket %d\n", preauthSocket->drvSocket);
491 eapd_preauth_close(preauthSocket->drvSocket);
492 preauthSocket->drvSocket = -1;
494 #endif
495 tmp_cb = cb;
496 cb = cb->next;
497 free(tmp_cb);
500 /* close appSocke */
501 if (nas->appSocket >= 0) {
502 EAPD_INFO("close nas appSocket %d\n", nas->appSocket);
503 close(nas->appSocket);
504 nas->appSocket = -1;
507 return 0;
510 /* nas_sendup will send eapol, brcm and preauth packet */
512 nas_app_sendup(eapd_wksp_t *nwksp, uint8 *pData, int pLen, char *from)
514 eapd_nas_t *nas;
516 if (nwksp == NULL) {
517 EAPD_ERROR("Wrong argument...\n");
518 return -1;
521 nas = &nwksp->nas;
522 if (nas->appSocket >= 0) {
523 /* send to nas */
524 int sentBytes = 0;
525 struct sockaddr_in to;
527 to.sin_addr.s_addr = inet_addr(EAPD_WKSP_UDP_ADDR);
528 to.sin_family = AF_INET;
529 to.sin_port = htons(EAPD_WKSP_NAS_UDP_SPORT);
531 sentBytes = sendto(nas->appSocket, (char *)pData, pLen, 0,
532 (struct sockaddr *)&to, sizeof(struct sockaddr_in));
534 if (sentBytes != pLen) {
535 EAPD_ERROR("UDP send failed; sentBytes = %d\n", sentBytes);
537 else {
538 /* EAPD_ERROR("Send %d bytes to nas\n", sentBytes); */
541 else {
542 EAPD_ERROR("nas appSocket not created\n");
544 return 0;
547 #if EAPD_WKSP_AUTO_CONFIG
549 nas_app_enabled(char *name)
551 char value[128], comb[32], akm[16], prefix[8];
552 char akms[128], auth[32], wep[32], crypto[32], os_name[IFNAMSIZ];
553 char *akmnext;
554 uint wsec, nasm;
555 int unit;
557 memset(os_name, 0, sizeof(os_name));
559 if (nvifname_to_osifname(name, os_name, sizeof(os_name)))
560 return 0;
561 if (wl_probe(os_name) ||
562 wl_ioctl(os_name, WLC_GET_INSTANCE, &unit, sizeof(unit)))
563 return 0;
564 if (osifname_to_nvifname(name, prefix, sizeof(prefix)))
565 return 0;
567 strcat(prefix, "_");
568 /* ignore if disabled */
569 eapd_safe_get_conf(value, sizeof(value), strcat_r(prefix, "radio", comb));
570 if (atoi(value) == 0) {
571 EAPD_INFO("NAS:ignored interface %s. radio disabled\n", os_name);
572 return 0;
574 /* ignore shared */
575 eapd_safe_get_conf(value, sizeof(value), strcat_r(prefix, "auth", comb));
576 if (atoi(value) == 1) {
577 EAPD_INFO("NAS: ignored interface %s. Shared 802.11 auth\n", os_name);
578 return 0;
580 /* ignore if BSS is disabled */
581 eapd_safe_get_conf(value, sizeof(value), strcat_r(prefix, "bss_enabled", comb));
582 if (atoi(value) == 0) {
583 EAPD_INFO("NAS: ignored interface %s, %s is disabled \n", os_name, comb);
584 return 0;
586 /* nas mode */
587 eapd_safe_get_conf(auth, sizeof(auth), strcat_r(prefix, "auth_mode", comb));
588 nasm = !strcmp(auth, "radius") ? RADIUS : 0;
589 eapd_safe_get_conf(akms, sizeof(akms), strcat_r(prefix, "akm", comb));
590 foreach(akm, akms, akmnext) {
591 if (!strcmp(akm, "wpa"))
592 nasm |= WPA;
593 if (!strcmp(akm, "psk"))
594 nasm |= WPA_PSK;
595 #ifdef BCMWPA2
596 if (!strcmp(akm, "wpa2"))
597 nasm |= WPA2;
598 if (!strcmp(akm, "psk2"))
599 nasm |= WPA2_PSK;
600 #endif
602 if (!nasm) {
603 EAPD_INFO("NAS:ignored interface %s. Invalid NAS mode\n", os_name);
604 return 0;
606 /* wsec */
607 eapd_safe_get_conf(wep, sizeof(wep), strcat_r(prefix, "wep", comb));
608 wsec = !strcmp(wep, "enabled") ? WEP_ENABLED : 0;
609 if (CHECK_NAS(nasm)) {
610 eapd_safe_get_conf(crypto, sizeof(crypto), strcat_r(prefix, "crypto", comb));
611 if (!strcmp(crypto, "tkip"))
612 wsec |= TKIP_ENABLED;
613 else if (!strcmp(crypto, "aes"))
614 wsec |= AES_ENABLED;
615 else if (!strcmp(crypto, "tkip+aes"))
616 wsec |= TKIP_ENABLED|AES_ENABLED;
618 if (!wsec) {
619 EAPD_INFO("%s: Ignored interface. Invalid WSEC\n", os_name);
620 return 0;
623 /* if come to here return enabled */
624 return 1;
626 #endif /* EAPD_WKSP_AUTO_CONFIG */
629 nas_app_handle_event(eapd_wksp_t *nwksp, uint8 *pData, int Len, char *from)
631 int type;
632 eapd_nas_t *nas;
633 eapd_cb_t *cb;
634 bcm_event_t *dpkt = (bcm_event_t *) pData;
635 wl_event_msg_t *event = &(dpkt->event);
636 uint8 *addr = (uint8 *)&(event->addr);
637 uint8 *data = (uint8 *)(event + 1);
638 uint16 len = ntoh32(event->datalen);
639 uint32 mode, wsec;
640 eapd_sta_t *sta;
643 type = ntohl(event->event_type);
645 nas = &nwksp->nas;
646 cb = nas->cb;
647 while (cb) {
648 if (isset(nas->bitvec, type) &&
649 !strcmp(cb->ifname, from)) {
650 /* We need to know is client in PSK mode */
651 if (type == WLC_E_ASSOC_IND || type == WLC_E_REASSOC_IND ||
652 type == WLC_E_DISASSOC_IND || type == WLC_E_DEAUTH_IND) {
653 sta = sta_lookup(nwksp, (struct ether_addr *)addr,
654 (struct ether_addr *) dpkt->eth.ether_dhost,
655 event->ifname, EAPD_SEARCH_ENTER);
656 if (!sta) {
657 EAPD_ERROR("no STA struct available\n");
658 return -1;
661 if (type == WLC_E_DISASSOC_IND || type == WLC_E_DEAUTH_IND) {
662 /* Reset the sta mode */
663 sta->mode = EAPD_STA_MODE_UNKNOW;
665 else if (!nas_app_parse_ie(data, len, &wsec, &mode) &&
666 CHECK_PSK(mode)) {
667 /* set cient in PSK mode */
668 sta->mode = EAPD_STA_MODE_NAS_PSK;
672 /* prepend ifname, we reserved IFNAMSIZ length already */
673 pData -= IFNAMSIZ;
674 Len += IFNAMSIZ;
675 memcpy(pData, event->ifname, IFNAMSIZ);
677 /* send to nas use cb->ifname */
678 nas_app_sendup(nwksp, pData, Len, cb->ifname);
679 break;
681 cb = cb->next;
684 return 0;