/* * Manage Join State. */ CWStateTransition CWWTPEnterJoin() { CWTimerID waitJoinTimer; int seqNum; CWProtocolJoinResponseValues values; CWLog("\n"); CWLog("######### Join State #########"); /* reset Join state */ CWNetworkCloseSocket(gWTPSocket); CWSecurityDestroySession(gWTPSession); CWSecurityDestroyContext(gWTPSecurityContext); gWTPSecurityContext = NULL; gWTPSession = NULL; /* Initialize gACInfoPtr */ gACInfoPtr->ACIPv4ListInfo.ACIPv4ListCount=0; gACInfoPtr->ACIPv4ListInfo.ACIPv4List=NULL; gACInfoPtr->ACIPv6ListInfo.ACIPv6ListCount=0; gACInfoPtr->ACIPv6ListInfo.ACIPv6List=NULL; if ((waitJoinTimer = timer_add(gCWWaitJoin, 0, CWWTPWaitJoinExpired, NULL)) == -1) { return CW_ENTER_DISCOVERY; } if(gWTPForceACAddress != NULL) { CW_CREATE_OBJECT_ERR(gACInfoPtr, CWACInfoValues, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL););
void CWACEnterMainLoop() { struct sigaction act; CWLog("AC enters in the MAIN_LOOP"); /* set signals * all the thread we spawn will inherit these settings */ /* * BUG UMR03 * * 20/10/2009 - Donato Capitella */ sigemptyset(&act.sa_mask); act.sa_flags = 0; /* called when a timer requested by the thread has expired */ act.sa_handler = CWCriticalTimerExpiredHandler; sigaction(CW_CRITICAL_TIMER_EXPIRED_SIGNAL, &act, NULL); act.sa_flags = 0; /* called when a timer requested by the thread has expired */ act.sa_handler = CWSoftTimerExpiredHandler; sigaction(CW_SOFT_TIMER_EXPIRED_SIGNAL, &act, NULL); /* signals will be unblocked by the threads that needs timers */ CWThreadSetSignals(SIG_BLOCK, 2, CW_CRITICAL_TIMER_EXPIRED_SIGNAL, CW_SOFT_TIMER_EXPIRED_SIGNAL); if(!(CWThreadCreateSpecific(&gIndexSpecific, NULL))) { CWLog("Critical Error With Thread Data"); exit(1); } CWThread thread_interface; if(!CWErr(CWCreateThread(&thread_interface, CWInterface, NULL))) { CWLog("Error starting Interface Thread"); exit(1); } CW_REPEAT_FOREVER { /* CWACManageIncomingPacket will be called * when a new packet is ready to be read */ if(!CWErr(CWNetworkUnsafeMultiHomed(&gACSocket, CWACManageIncomingPacket, CW_FALSE))) exit(1); } }
void CWLogInitFile(char *fileName) { if(fileName == NULL) { CWLog("Wrong File Name for Log File"); } if((gLogFile = fopen(fileName, "w")) == NULL) { CWLog("Can't open log file: %s", strerror(errno)); exit(1); } #ifndef CW_SINGLE_THREAD if(!CWCreateThreadMutex(&gFileMutex)) { CWLog("Can't Init File Mutex for Log"); exit(1); } #endif }
CWBool CWACSendFragments(int WTPIndex) { int i; if (gWTPs[WTPIndex].messages == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); for (i = 0; i < gWTPs[WTPIndex].messagesCount; i++) { #ifdef CW_NO_DTLS if (!CWNetworkSendUnsafeUnconnected(gWTPs[WTPIndex].socket, &gWTPs[WTPIndex].address, gWTPs[WTPIndex].messages[i].msg, gWTPs[WTPIndex].messages[i].offset)) { #else if (! (CWSecuritySend (gWTPs[WTPIndex].session, gWTPs[WTPIndex].messages[i].msg, gWTPs[WTPIndex].messages[i].offset))) { #endif return CW_FALSE; } } /* * BUG - ML12 * * 20/10/2009 - Donato Capitella */ CW_FREE_WTP_MSG_ARRAY(WTPIndex); CWLog("Message Sent\n"); return CW_TRUE; } CWBool CWACResendAcknowledgedPacket(int WTPIndex) { if (!CWACSendFragments(WTPIndex)) return CW_FALSE; CWThreadSetSignals(SIG_BLOCK, 1, CW_SOFT_TIMER_EXPIRED_SIGNAL); if (! (CWTimerRequest (gCWRetransmitTimer, &(gWTPs[WTPIndex].thread), &(gWTPs[WTPIndex].currentPacketTimer), CW_SOFT_TIMER_EXPIRED_SIGNAL))) { return CW_FALSE; } CWThreadSetSignals(SIG_UNBLOCK, 1, CW_SOFT_TIMER_EXPIRED_SIGNAL); return CW_TRUE; } __inline__ CWBool CWACSendAcknowledgedPacket(int WTPIndex, int msgType, int seqNum) { gWTPs[WTPIndex].retransmissionCount = 0; gWTPs[WTPIndex].isRetransmitting = CW_TRUE; gWTPs[WTPIndex].responseType = msgType; gWTPs[WTPIndex].responseSeqNum = seqNum; // CWDebugLog("~~~~~~seq num in Send: %d~~~~~~", gWTPs[WTPIndex].responseSeqNum); return CWACResendAcknowledgedPacket(WTPIndex); }
static int memory_read(BIO *b, char *out, int outl) { int ret = -1; char* buf; int size; BIO_memory_data* pData = (BIO_memory_data*)b->ptr; // //BIO_clear_retry_flags(b); // CWLockSafeList(pData->pRecvAddress); // Used only in DTLS handshake while (CWGetCountElementFromSafeList(pData->pRecvAddress) == 0){ CWWaitElementFromSafeList(pData->pRecvAddress); } buf = (char*)CWRemoveHeadElementFromSafeList(pData->pRecvAddress, &size); CWUnlockSafeList(pData->pRecvAddress); if ((buf == NULL) || (size <= 0)) CWLog("Warning empty buffer"); else { ret = ((size < outl) ? size : outl) - 4; memcpy(out, buf + 4, ret); CW_FREE_OBJECT(buf); } return ret; }
CWBool CWAssembleWTPVendorPayloadUCI(CWProtocolMessage *msgPtr) { int* iPtr; unsigned short msgType; CWProtocolVendorSpecificValues* valuesPtr; CWVendorUciValues* uciPtr; CWLog("Assembling Protocol Configuration Update Request [VENDOR CASE]..."); if(msgPtr == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); if((iPtr = ((int*)CWThreadGetSpecific(&gIndexSpecific))) == NULL) { return CW_FALSE; } valuesPtr =gWTPs[*iPtr].vendorValues; switch (valuesPtr->vendorPayloadType){ case CW_MSG_ELEMENT_VENDOR_SPEC_PAYLOAD_UCI: msgType = CW_MSG_ELEMENT_VENDOR_SPEC_PAYLOAD_UCI; uciPtr = (CWVendorUciValues *) valuesPtr->payload; if (uciPtr->commandArgs != NULL) { /* create message */ CW_CREATE_PROTOCOL_MESSAGE(*msgPtr, sizeof(short)+sizeof(char)+sizeof(int)+(strlen(uciPtr->commandArgs)*sizeof(char)), return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL);); CWProtocolStore16(msgPtr, (unsigned short) msgType); CWProtocolStore8(msgPtr, (unsigned char) uciPtr->command); CWProtocolStore32(msgPtr, (unsigned int) strlen(uciPtr->commandArgs)); CWProtocolStoreStr(msgPtr, uciPtr->commandArgs); } else {
/* * Manage DTLS packets. */ CW_THREAD_RETURN_TYPE CWWTPReceiveDtlsPacket(void *arg) { int readBytes; unsigned char buf[CW_BUFFER_SIZE]; CWSocket sockDTLS = (long) arg; CWNetworkLev4Address addr; char *pData; CW_REPEAT_FOREVER { if (!CWErr(CWNetworkReceiveUnsafe(sockDTLS, buf, CW_BUFFER_SIZE - 1, 0, &addr, &readBytes))) { if (CWErrorGetLastErrorCode() == CW_ERROR_INTERRUPTED) continue; break; } /* Clone data packet */ CW_CREATE_OBJECT_SIZE_ERR(pData, readBytes, { CWLog("Out Of Memory"); return NULL; } ); memcpy(pData, buf, readBytes); CWLockSafeList(gPacketReceiveList); CWAddElementToSafeListTailwitDataFlag(gPacketReceiveList, pData, readBytes, CW_FALSE); CWUnlockSafeList(gPacketReceiveList); }
void CW80211ManagementFrameEvent(struct nl_handle **handleMgmt, cw_sock_handler handler, void * cb, struct WTPBSSInfo * BSSInfo) { //Set file descriptor of socket to non-blocking state nl_socket_set_nonblocking(*handleMgmt); int nlSocketFDmgmt = nl_socket_get_fd(*handleMgmt); CWBool exitThread=CW_FALSE; while(1) { //On delete BSS CWThreadMutexLock(&(BSSInfo->bssMutex)); exitThread = BSSInfo->destroyBSS; CWThreadMutexUnlock(&(BSSInfo->bssMutex)); if(exitThread == CW_TRUE) CWExitThread(); int result; fd_set readset; do { FD_ZERO(&readset); FD_SET(nlSocketFDmgmt, &readset); result = select(nlSocketFDmgmt + 1, &readset, NULL, NULL, NULL); } while (result == -1 && errno == EINTR); if (result > 0) { if (FD_ISSET(nlSocketFDmgmt, &readset)) { handler(cb, (*handleMgmt)); } } else if (result < 0) { CWLog("Error on select(): %s", strerror(errno)); } } }
/* * Init multihomed socket. Will bind a socket for each interface + each * broadcast address + the wildcard addres + each multicast address in * multicastGroups. */ CWBool CWNetworkInitSocketServerMultiHomed(CWMultiHomedSocket * sockPtr, int port, char **multicastGroups, int multicastGroupsCount) { struct ifi_info *ifi, *ifihead; CWNetworkLev4Address wildaddr; int yes = 1; CWSocket sock; CWMultiHomedInterface *p; CWList interfaceList = CW_LIST_INIT; CWListElement *el = NULL; int i; if (sockPtr == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); sockPtr->count = 0; /* * note: if get_ifi_info is called with AF_INET6 on an host that doesn't * support IPv6, it'll simply act like if it was called with AF_INET. * Consider aliases as different interfaces (last arg of get_ifi_info is 1). * Why? Just to increase the funny side of the thing. */ #ifdef CW_DEBUGGING /* for each network interface... */ for (ifihead = ifi = get_ifi_info((gNetworkPreferredFamily == CW_IPv6) ? AF_INET6 : AF_INET, 1); ifi != NULL; ifi = ifi->ifi_next) { #else /* for each network interface... */ for (ifihead = ifi = get_ifi_info((gNetworkPreferredFamily == CW_IPv6) ? AF_INET6 : AF_INET, 0); ifi != NULL; ifi = ifi->ifi_next) { #endif /* bind a unicast address */ if ((sock = socket(ifi->ifi_addr->sa_family, SOCK_DGRAM, 0)) < 0) { free_ifi_info(ifihead); CWNetworkRaiseSystemError(CW_ERROR_CREATING); } /* reuse address */ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); /* bind address */ sock_set_port_cw(ifi->ifi_addr, htons(port)); if (bind (sock, (struct sockaddr *)ifi->ifi_addr, CWNetworkGetAddressSize((CWNetworkLev4Address *) ifi->ifi_addr)) < 0) { close(sock); CWUseSockNtop(ifi->ifi_addr, CWDebugLog("failed %s", str); ); continue; /* CWNetworkRaiseSystemError(CW_ERROR_CREATING); */ } CWUseSockNtop(ifi->ifi_addr, CWLog("bound %s (%d, %s)", str, ifi->ifi_index, ifi->ifi_name); );
/* ------------------------------------------------ */ CW_THREAD_RETURN_TYPE CWWTPBSSManagement(void *arg){ struct WTPBSSInfo * BSSInfo = (struct WTPBSSInfo *) arg; CWLog("New thread created for BSS SSID: %s", BSSInfo->interfaceInfo->SSID); //Start reading from AP readers CW80211ManagementFrameEvent(&(BSSInfo->interfaceInfo->nl_mgmt), CW80211EventReceive, BSSInfo->interfaceInfo->nl_cb, BSSInfo); }
CW_THREAD_RETURN_TYPE CWWTPFreqManager(void *arg) { int recSock, rlen; struct sockaddr_in servaddr, client_addr; socklen_t slen = sizeof(client_addr); char buffer[PACKET_SIZE]; OFDMControlValues* freqValue; int current_chan=0; CWProtocolMessage *completeMsgPtr = NULL; CWThreadSetSignals(SIG_BLOCK, 1, SIGALRM); /* Create an Inet UDP socket for this thread (Receive freq/ack packets) */ if ((recSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { CWDebugLog("Thread Frequency Management: Error creating socket"); CWExitThread(); } /* Set up address structure for server socket */ servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); servaddr.sin_port = htons(SERVER_PORT); /* Binding Socket */ if (bind(recSock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr_in)) < 0) { CWDebugLog("Thread Frequency Management: Binding Socket Error"); close(recSock); CWExitThread(); } CW_REPEAT_FOREVER /* Receive data Loop */ { memset(buffer, 0, PACKET_SIZE); rlen = 0; if ( ( rlen = recvfrom(recSock, buffer, PACKET_SIZE, 0, (struct sockaddr *) &client_addr, &slen) ) > 0 ) { freqValue = (OFDMControlValues*) buffer; current_chan = freqValue->currentChan; if(!CWSetCurrentChannel(current_chan)) { CWLog("Thread Frequency Management: Failed to set current channel value."); continue; } } } CWDebugLog("Thread Frequency Management: Thread ended unexpectedly!!"); close(recSock); CWExitThread(); }
CWBool ACEnterJoin(int WTPIndex, CWProtocolMessage *msgPtr) { int seqNum; CWProtocolJoinRequestValues joinRequest; CWList msgElemList = NULL; CWLog("\n"); CWLog("######### Join State #########"); if(msgPtr == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); if(!(CWParseJoinRequestMessage(msgPtr->msg, msgPtr->offset, &seqNum, &joinRequest))) { /* note: we can kill our thread in case of out-of-memory * error to free some space. * we can see this just calling CWErrorGetLastErrorCode() */ return CW_FALSE; } // cancel waitJoin timer if(!CWTimerCancel(&(gWTPs[WTPIndex].currentTimer))) { return CW_FALSE; } CWBool ACIpv4List = CW_FALSE; CWBool ACIpv6List = CW_FALSE; CWBool resultCode = CW_TRUE; int resultCodeValue = CW_PROTOCOL_SUCCESS; /* CWBool sessionID = CW_FALSE; */ if(!(CWSaveJoinRequestMessage(&joinRequest, &(gWTPs[WTPIndex].WTPProtocolManager)))) { resultCodeValue = CW_PROTOCOL_FAILURE_RES_DEPLETION; } CWMsgElemData *auxData; if(ACIpv4List) { CW_CREATE_OBJECT_ERR(auxData, CWMsgElemData, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL);); auxData->type = CW_MSG_ELEMENT_AC_IPV4_LIST_CW_TYPE; auxData->value = 0; CWAddElementToList(&msgElemList,auxData); }
CWBool checkResetFile(){ long fileSize=0; if((fileSize=ftell(gLogFile))==-1) { CWLog("An error with log file occurred: %s", strerror(errno)); return 0; } if (fileSize>=gMaxLogFileSize) { fclose(gLogFile); if((gLogFile = fopen(gLogFileName, "w")) == NULL) { CWLog("Can't open log file: %s", strerror(errno)); return 0; } } return 1; }
void CWWTPsend_command_to_hostapd_CLOSE(unsigned char *buf, int len){ buf[0] = CLOSE; if( sendto(sock, buf, len, 0, (struct sockaddr *)&client, address_size)<0 ){ CWLog("Error to send command frame on socket"); return; } }
void CWCreateConnectionWithHostapdAC() { CWThread thread_ipc_with_ac_hostapd; if (!CWErr(CWCreateThread(&thread_ipc_with_ac_hostapd, CWACipc_with_ac_hostapd, NULL))) { CWLog("Error starting Thread that receive command and 802.11 frame from hostapd (WTP side)"); exit(1); } }
void CWWTPsend_command_to_hostapd_DEL_ADDR(unsigned char *buf, int len){ if(!connected)return; buf[0] = DEL_ADDR; if( sendto(sock, buf, len, 0, (struct sockaddr *)&client, address_size)<0 ){ CWLog("Error to send command frame on socket"); return; } }
__inline__ int CWACGetActiveWTPs() { int tmp; if(!CWErr(CWThreadMutexLock(&gActiveWTPsMutex))) { CWLog("F:%s L:%d Error locking mutex",__FILE__,__LINE__); return 0; } tmp = gActiveWTPs; CWThreadMutexUnlock(&gActiveWTPsMutex); return tmp; }
/*Begin:zengmin add return because fileName may be null by Coverity Dereference before null check 2013-06-08 */ void CWLogInitFile(char *fileName) { if(fileName == NULL) { CWLog("Wrong File Name for Log File"); return; } if((gLogFile = autelan_fopen(fileName, "a")) == NULL) { CWLog("%s,Can't open log file:%s.", strerror(errno),fileName); //exit(1); return; } #ifndef CW_SINGLE_THREAD if(!CWCreateThreadMutex(&gFileMutex)) { CWLog("Can't Init File Mutex for Log"); //exit(1); return; } #endif return; }
CWBool ACEnterConfigure(int WTPIndex, CWProtocolMessage *msgPtr) { int seqNum; CWProtocolConfigureRequestValues configureRequest; CWLog("\n"); CWLog("######### Configure State #########"); if(!(CWParseConfigureRequestMessage(msgPtr->msg, msgPtr->offset, &seqNum, &configureRequest))) { /* note: we can kill our thread in case of out-of-memory * error to free some space. * we can see this just calling CWErrorGetLastErrorCode() */ return CW_FALSE; } CWLog("Configure Request Received"); if(!(CWSaveConfigureRequestMessage(&configureRequest, &(gWTPs[WTPIndex].WTPProtocolManager)))){ return CW_FALSE; } if(!(CWAssembleConfigureResponse(&(gWTPs[WTPIndex].messages), &(gWTPs[WTPIndex].messagesCount), gWTPs[WTPIndex].pathMTU, seqNum))) { return CW_FALSE; } if(!CWACSendFragments(WTPIndex)) { return CW_FALSE; } CWLog("Configure Response Sent"); /* Destroy ConfigStatePending timer */ if(!CWErr(CWTimerCancel(&(gWTPs[WTPIndex].currentTimer)))) { CWLog("%s %d [%d] CWTimerCancel Fail, close thread!",__FILE__,__LINE__,WTPIndex); //CWCloseThread(); gWTPs[WTPIndex].isRequestClose = CW_TRUE; return CW_FALSE; } /* start Change State Pending timer */ if(!CWErr(CWTimerRequest(gCWChangeStatePendingTimer, &(gWTPs[WTPIndex].thread), &(gWTPs[WTPIndex].currentTimer), CW_CRITICAL_TIMER_EXPIRED_SIGNAL))) { CWLog("%s %d [%d] CWTimerRequest Fail, close thread!",__FILE__,__LINE__,WTPIndex); //CWCloseThread(); gWTPs[WTPIndex].isRequestClose = CW_TRUE; return CW_FALSE; } //CWLog("CWTimerRequest Success !!!"); gWTPs[WTPIndex].currentState = CW_ENTER_DATA_CHECK; return CW_TRUE; }
void CW80211EventReceive(void *cbPtr, void *handlePtr) { struct nl_cb *cb = (struct nl_cb *) cbPtr; struct nl_handle * handle = (struct nl_handle *) handlePtr; int res; //CWLog("nl80211: Event message available"); res = nl_recvmsgs(handle, cb); if (res < 0) { CWLog("nl80211: %s->nl_recvmsgs failed: %d, %s", __func__, res, strerror(res)); } }
int tun_alloc(char *dev, int flags) { struct ifreq ifr; int fd, err; char *clonedev = "/dev/net/tun"; /* Arguments taken by the function: * * char *dev: the name of an interface (or '\0'). MUST have enough * space to hold the interface name if '\0' is passed * int flags: interface flags (eg, IFF_TUN etc.) */ /* open the clone device */ if( (fd = open(clonedev, O_RDWR)) < 0 ) { return fd; } /* preparation of the struct ifr, of type "struct ifreq" */ memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */ if (*dev) { /* if a device name was specified, put it in the structure; otherwise, * the kernel will try to allocate the "next" device of the * specified type */ strncpy(ifr.ifr_name, dev, IFNAMSIZ); } /* try to create the device */ if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) { CWLog("Err to creater tap device"); close(fd); return err; } /* if the operation was successful, write back the name of the * interface to the variable "dev", so the caller can know * it. Note that the caller MUST reserve space in *dev (see calling * code below) */ strcpy(dev, ifr.ifr_name); /* this is the special file descriptor that the caller will use to talk * with the virtual interface */ return fd; }
void CWWTPsend_command_to_hostapd_DEL_WLAN(unsigned char *buf, int len) { WAITHOSTAPDDEL: if (!connected) { sleep(0.2); goto WAITHOSTAPDDEL; } buf[0] = DEL_WLAN; if (sendto(sock, buf, len, 0, (struct sockaddr *)&client, address_size) < 0) { CWLog("Error to send command DEL WLAN on socket"); return; } }
int CWACSemPostForOpenSSLHack(void *s) { CWThreadTimedSem *semPtr = (CWThreadTimedSem*) s; if(!CWThreadTimedSemIsZero(semPtr)) { CWLog("This Semaphore's Value should really be 0"); /* note: we can consider setting the value to 0 and going on, * that is what we do here */ if(!CWErr(CWThreadTimedSemSetValue(semPtr, 0))) return 0; } if(!CWErr(CWThreadTimedSemPost(semPtr))) { return 0; } return 1; }
CWBool ACEnterDataCheck(int WTPIndex, CWProtocolMessage * msgPtr) { /*CWProtocolMessage *messages = NULL; */ int seqNum; CWProtocolChangeStateEventRequestValues *changeStateEvent; CWLog("\n"); CWDebugLog("######### Status Event #########"); /* Destroy ChangeStatePending timer */ if (!CWErr(CWTimerCancel(&(gWTPs[WTPIndex].currentTimer)))) { CWCloseThread(); } CW_CREATE_OBJECT_ERR(changeStateEvent, CWProtocolChangeStateEventRequestValues, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL); );
/*Update 2009: Assemble protocol Configuration update request. Mainly added to manage vendor specific packets*/ CWBool CWProtocolAssembleConfigurationUpdateRequest(CWProtocolMessage ** msgElems, int *msgElemCountPtr, int MsgElementType) { int *iPtr; int k = -1; if (msgElems == NULL || msgElemCountPtr == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); if ((iPtr = ((int *)CWThreadGetSpecific(&gIndexSpecific))) == NULL) { return CW_FALSE; } *msgElemCountPtr = 1; CWLog("Assembling Protocol Configuration Update Request..."); CW_CREATE_PROTOCOL_MSG_ARRAY_ERR(*msgElems, *msgElemCountPtr, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL); );
/* * This callback function is called when there is something to read in a * CWMultiHomedSocket (see ACMultiHomed.c). * * Params: sock, is the socket that can receive the packet and it can be * used to reply. * buf, (array of len chars) contains the packet which is ready * on the socket's queue (obtained with MSG_PEEK). * incomingInterfaceIndex, is the index (different from the system * index, see ACMultiHomed.c) of the interface * the packet was sent to, in the array returned * by CWNetworkGetInterfaceAddresses. If the * packet was sent to a broadcast/multicast address, * incomingInterfaceIndex is -1. */ void CWACManageIncomingPacket(CWSocket sock, char *buf, int readBytes, int incomingInterfaceIndex, CWNetworkLev4Address *addrPtr,CWBool dataFlag) { CWWTPManager *wtpPtr = NULL; char* pData; /* check if sender address is known */ wtpPtr = CWWTPByAddress(addrPtr, sock); if ((wtpPtr != NULL) && dataFlag && (wtpPtr->dataaddress.ss_family == AF_UNSPEC)) { CW_COPY_NET_ADDR_PTR(&(wtpPtr->dataaddress), addrPtr); } if(wtpPtr != NULL) { /* known WTP */ /* Clone data packet */ CW_CREATE_OBJECT_SIZE_ERR(pData, readBytes, { CWLog("Out Of Memory"); return; });
/* send Discovery Response to the host at the specified address */ CWBool CWAssembleDiscoveryResponse(CWProtocolMessage ** messagesPtr, int seqNum) { CWProtocolMessage *msgElems = NULL; int msgElemCount = 4; CWProtocolMessage *msgElemsBinding = NULL; int msgElemBindingCount = 0; int fragmentsNum; int k = -1; if (messagesPtr == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); if (CWACSupportIPv6()) { msgElemCount++; } CWLog("Send Discovery Response"); CW_CREATE_PROTOCOL_MSG_ARRAY_ERR(msgElems, msgElemCount, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL); );
CWBool CWParseSettingsFile() { char *line = NULL; gSettingsFile = fopen (CW_SETTINGS_FILE, "rb"); if (gSettingsFile == NULL) { CWErrorRaiseSystemError(CW_ERROR_GENERAL); } while((line = (char*)CWGetCommand(gSettingsFile)) != NULL) { char* startTag=NULL; char* endTag=NULL; if((startTag=strchr (line, '<'))==NULL) { CW_FREE_OBJECT(line); continue; } if((endTag=strchr (line, '>'))==NULL) { CW_FREE_OBJECT(line); continue; } if (!strncmp(startTag+1, "IF_NAME", endTag-startTag-1)) { char* startValue=NULL; char* endValue=NULL; int offset = 0; CWExtractValue(endTag, &startValue, &endValue, &offset); CW_CREATE_STRING_ERR(gInterfaceName, offset, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY,NULL);); strncpy(gInterfaceName, startValue, offset); gInterfaceName[offset] ='\0'; CWLog(": %s", gInterfaceName); CW_FREE_OBJECT(line); continue; }
void CWACDestroy() { CWNetworkCloseMultiHomedSocket(&gACSocket); /* for(i = 0; i < CW_MAX_WTP; i++) { //CW_FREE_OBJECT(gWTPs[i].addr); } */ #ifndef CW_NO_DTLS CWSslCleanUp(); #endif CWDestroyThreadMutex(&gWTPsMutex); CWDestroyThreadMutex(&gCreateIDMutex); CWDestroyThreadMutex(&gActiveWTPsMutex); CW_FREE_OBJECT(gACName); CW_FREE_OBJECT(gInterfaces); CWLog("AC Destroyed"); }
/* * Manage Discovery State */ CWStateTransition CWWTPEnterDiscovery() { int i; CWBool j; CWLog("\n"); CWLog("######### Discovery State #########"); /* reset Discovery state */ gCWDiscoveryCount = 0; CWNetworkCloseSocket(gWTPSocket); if (!CWErr(CWNetworkInitSocketClient(&gWTPSocket, NULL))) { return CW_QUIT; } /* * note: gCWACList can be freed and reallocated (reading from config file) * at each transition to the discovery state to save memory space */ for (i = 0; i < gCWACCount; i++) gCWACList[i].received = CW_FALSE; /* wait a random time */ sleep(CWRandomIntInRange(gCWDiscoveryInterval, gCWMaxDiscoveryInterval)); CW_REPEAT_FOREVER { CWBool sentSomething = CW_FALSE; /* we get no responses for a very long time */ if (gCWDiscoveryCount == gCWMaxDiscoveries) return CW_ENTER_SULKING; /* send Requests to one or more ACs */ for (i = 0; i < gCWACCount; i++) { /* if this AC hasn't responded to us... */ if (!(gCWACList[i].received)) { /* ...send a Discovery Request */ CWProtocolMessage *msgPtr = NULL; /* get sequence number (and increase it) */ gCWACList[i].seqNum = CWGetSeqNum(); if (!CWErr(CWAssembleDiscoveryRequest(&msgPtr, gCWACList[i].seqNum))) { exit(1); } CW_CREATE_OBJECT_ERR(gACInfoPtr, CWACInfoValues, return CW_QUIT; ); CWNetworkGetAddressForHost(gCWACList[i].address, &(gACInfoPtr->preferredAddress)); CWUseSockNtop(&(gACInfoPtr->preferredAddress), CWDebugLog(str); ); j = CWErr(CWNetworkSendUnsafeUnconnected(gWTPSocket, &(gACInfoPtr->preferredAddress), (*msgPtr).msg, (*msgPtr).offset)); /* * log eventual error and continue * CWUseSockNtop(&(gACInfoPtr->preferredAddress), * CWLog("WTP sends Discovery Request to: %s", str);); */ CW_FREE_PROTOCOL_MESSAGE(*msgPtr); CW_FREE_OBJECT(msgPtr); CW_FREE_OBJECT(gACInfoPtr); /* * we sent at least one Request in this loop * (even if we got an error sending it) */ sentSomething = CW_TRUE; }