示例#1
0
int CWWTPSendFrame(unsigned char *buf, int len){
    int FRAME_80211_LEN=24;
    int gRawSockLocal;
    struct sockaddr_ll addr;
    
    if ((gRawSockLocal=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)))<0) 	{
		CWDebugLog("THR FRAME: Error creating socket");
		CWExitThread();
	}

    memset(&addr, 0, sizeof(addr));
	addr.sll_family = AF_PACKET;
//	addr.sll_protocol = htons(ETH_P_ALL);
//	addr.sll_pkttype = PACKET_HOST;
	addr.sll_ifindex = if_nametoindex("monitor0"); //if_nametoindex(gRadioInterfaceName_0);
 
	 
	if ((bind(gRawSockLocal, (struct sockaddr*)&addr, sizeof(addr)))<0) {
 		CWDebugLog("THR FRAME: Error binding socket");
 		CWExitThread();
 	}
 	
    if( send(gRawSockLocal, buf + FRAME_80211_LEN, len - FRAME_80211_LEN,0) < 1 ){
        CWDebugLog("Error to send frame on raw socket");
        return -1;
    }
    CWDebugLog("Send (%d) bytes on raw socket",len - FRAME_80211_LEN);

    return 1;
    
}
示例#2
0
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();
}
CW_THREAD_RETURN_TYPE CWWTPReceiveFreqStats(void *arg)
{
	int recSock, rlen, k, fragmentsNum = 0;

	struct sockaddr_in servaddr, client_addr;
	socklen_t slen = sizeof(client_addr);

	char buffer[PACKET_SIZE];

	CWProtocolMessage *completeMsgPtr = NULL;
	CWProtocolMessage *data = NULL;
	CWBindingTransportHeaderValues *bindingValuesPtr = 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 Receive Stats: 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 Receive Stats: Binding Socket Error");
		close(recSock);
		CWExitThread();
	}

	CW_REPEAT_FOREVER /* Receive data Loop */
	{
		memset(buffer, 0, PACKET_SIZE);
		fragmentsNum = 0;
		k = 0;
		rlen = 0;

		if ( ( rlen = recvfrom(recSock, buffer, PACKET_SIZE, 0, (struct sockaddr *) &client_addr, &slen) ) > 0 )
		{
			/* Creation of stats/ack message for AC */

			CW_CREATE_OBJECT_ERR(data, CWProtocolMessage, return 0;);
			CW_CREATE_PROTOCOL_MESSAGE(*data, rlen, return 0;);
示例#4
0
CWBool CWWTPCheckForWTPEventRequest(){

	CWDebugLog("\n");
	CWDebugLog("#________ WTP Event Request Message (Run) ________#");
	
	/* Send WTP Event Request */
	CWList msgElemList = NULL;
	CWProtocolMessage *messages = NULL;
	int fragmentsNum = 0;
	int seqNum;
	int *pendingReqIndex;
		
	seqNum = CWGetSeqNum();

	CW_CREATE_OBJECT_ERR(pendingReqIndex, int, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL););
示例#5
0
void CWWTPsend_command_to_hostapd_ADD_WLAN(unsigned char *buf, int len)
{
	CWDebugLog("CWWTPsend_command_to_hostapd_ADD_WLAN()");
 WAITHOSTAPDADD:

	if (!connected) {
		sleep(0.2);
		goto WAITHOSTAPDADD;
	}
	buf[0] = ADD_WLAN;

	if (sendto(sock, buf, len, 0, (struct sockaddr *)&client, address_size) < 0) {
		CWDebugLog("Error to send command ADD WLAN on socket");
		return;
	}
}
/*
 * 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);
		    );
示例#7
0
CWBool CWSecurityInitSessionClient(CWSocket sock, CWNetworkLev4Address *addrPtr, CWSafeList packetReceiveList, CWSecurityContext ctx, CWSecuritySession *sessionPtr, int *PMTUPtr) {
	BIO *sbio = NULL;
	CWNetworkLev4Address peer;
	int peerlen = sizeof(peer);
	int i;

	if(ctx == NULL || sessionPtr == NULL || PMTUPtr == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL);
	
	if((*sessionPtr = SSL_new(ctx)) == NULL) {
		CWSecurityRaiseError(CW_ERROR_CREATING);
	}
	
	#ifdef CW_DEBUGGING
		CWDebugLog("My Certificate");
		PEM_write_X509(stdout, SSL_get_certificate(*sessionPtr));
	#endif
	
    if((sbio = BIO_new_memory(sock, addrPtr, packetReceiveList)) == NULL) {
		SSL_free(*sessionPtr);
		CWSecurityRaiseError(CW_ERROR_CREATING);
	}

	if (getsockname(sock, (struct sockaddr*)&peer, (void *)&peerlen) < 0) {
		SSL_free(*sessionPtr);
		CWSecurityRaiseSystemError(CW_ERROR_GENERAL);
	}
	
	i = BIO_ctrl_set_connected(sbio, 1, &peer);
	
	//BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); // TO-DO (pass MTU?)
	BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_MTU, 10000, NULL); // TO-DO if we don't set a big MTU, thw DTLS implementation will
														 // not be able to use a big certificate 
	

	// Let the verify_callback catch the verify_depth error so that we get
	// an appropriate error in the logfile.
	SSL_set_verify_depth((*sessionPtr), CW_DTLS_CERT_VERIFY_DEPTH + 1);

    SSL_set_read_ahead( (*sessionPtr), 1); // required by DTLS implementation to avoid data loss
	
    SSL_set_bio((*sessionPtr), sbio, sbio);
	SSL_set_connect_state((*sessionPtr));
	
	CWDebugLog("Before HS");
	CWSecurityManageSSLError(
			SSL_do_handshake(*sessionPtr), *sessionPtr, SSL_free(*sessionPtr););
示例#8
0
/*
@sock	:
@addrPtr	: Ä¿µÄµØÖ·
@buf	:
@len	:
*/
CWBool CWNetworkSendUnsafeUnconnected(CWSocket sock, 
				      CWNetworkLev4Address *addrPtr,
				      const char *buf,
				      int len) {

	if(buf == NULL || addrPtr == NULL) 
		return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL);
	
	CWUseSockNtop(addrPtr, CWDebugLog(str););
示例#9
0
void CWACsend_command_to_hostapd_SET_WTPRINFO(int WTPIndex, char* buf, int len){ 
	
	buf[0] = SET_WTPRINFO;
	if( sendto(sock, buf, len, 0, (struct sockaddr *)&ch[WTPIndex].client, ch[WTPIndex].address_size)<0 ){
		CWDebugLog("Error to send command frame on socket");
		return;
	}
	
}
示例#10
0
文件: tap.c 项目: wsljmlin/opencapwap
int init_AC_tap_interface(int WTPIndex)
{
      sprintf(gWTPs[WTPIndex].tap_name,"wtp%d", WTPIndex);
     
      gWTPs[WTPIndex].tap_fd = tun_alloc(gWTPs[WTPIndex].tap_name, IFF_TAP | IFF_NO_PI);

      CWDebugLog("gWTPs[%d].tap_name %s,tap_fd %d",WTPIndex,gWTPs[WTPIndex].tap_name,gWTPs[WTPIndex].tap_fd);
      
      return 0;
}
示例#11
0
void CWWTPsend_command_to_hostapd_SET_ADDR(unsigned char *buf, int len){ 

	if(!connected)return;
	buf[0] = SET_ADDR;
	
	if( sendto(sock, buf, len, 0, (struct sockaddr *)&client, address_size)<0 ){
		CWDebugLog("Error to send command frame on socket");
		return;
	}
	
}
示例#12
0
// Creates a thread that will execute a given function with a given parameter
CWBool CWCreateThread(CWThread *newThread, CW_THREAD_FUNCTION threadFunc, void *arg) {
	if(newThread == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL);
	
	CWDebugLog("Create Thread\n");
		
	if(pthread_create(newThread, NULL, threadFunc, arg) != 0) {
		return CWErrorRaise(CW_ERROR_NEED_RESOURCE, "Can't create thread (maybe there are too many other threads)");
	}

	return CW_TRUE;
}
示例#13
0
int getMacAddr(int sock, char* interface, unsigned char* macAddr){
	
	struct ifreq s;
	int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
	strcpy(s.ifr_name, interface);
	if(!ioctl(fd, SIOCGIFHWADDR, &s))
		memcpy(macAddr, s.ifr_addr.sa_data, MAC_ADDR_LEN);
	
	CWDebugLog("\n");

	return 1;
}
示例#14
0
void CWACsend_command_to_hostapd_HAVE_TO_WAIT(int WTPIndex){ 

	char buf[1];
	
	buf[0] = HAVE_TO_WAIT;
	
	if( sendto(sock, buf, 1, 0, (struct sockaddr *)&ch[WTPIndex].client, ch[WTPIndex].address_size)<0 ){
		CWDebugLog("Error to send command frame on socket");
		return;
	}
	
}
void CWACStopRetransmission(int WTPIndex)
{
	if (gWTPs[WTPIndex].isRetransmitting) {
		int i;
		CWDebugLog("Stop Retransmission");
		gWTPs[WTPIndex].isRetransmitting = CW_FALSE;
		CWThreadSetSignals(SIG_BLOCK, 1, CW_SOFT_TIMER_EXPIRED_SIGNAL);
		if (!CWTimerCancel(&(gWTPs[WTPIndex].currentPacketTimer))) {
			CWDebugLog("Error Cancelling a Timer... possible error!");
		}
		CWThreadSetSignals(SIG_UNBLOCK, 1, CW_SOFT_TIMER_EXPIRED_SIGNAL);
		gWTPs[WTPIndex].responseType = UNUSED_MSG_TYPE;
		gWTPs[WTPIndex].responseSeqNum = 0;

		for (i = 0; i < gWTPs[WTPIndex].messagesCount; i++) {
			CW_FREE_PROTOCOL_MESSAGE(gWTPs[WTPIndex].messages[i]);
		}

		CW_FREE_OBJECT(gWTPs[WTPIndex].messages);
//      CWDebugLog("~~~~~~ End of Stop Retransmission");
	}
}
示例#16
0
void CWWTPsend_data_to_hostapd(unsigned char *buf, int len){  
	
	if(!connected)return;
	
	unsigned char tmp_buf[CW_BUFFER_SIZE];
	tmp_buf[0] = DATE_TO_WTP;
	memcpy(tmp_buf + 1, buf, len);
	
	if( sendto(sock,tmp_buf,len+1,0,(struct sockaddr *)&client,address_size)<0 ){
		CWDebugLog("Error to send data frame on Unix socket");
		return;
	}
	
}
示例#17
0
void CWHandleTimer(CWTimerArg arg) {
	
	CWThreadTimerArg *a = (CWThreadTimerArg*)arg;
 	CWThread requestedThreadPtr = *(a->requestedThreadPtr);
 	int signalToRaise = a->signalToRaise;

	CWThreadSendSignal(requestedThreadPtr, signalToRaise);
 	CWDebugLog("Timer Expired, Sent Signal(%d) to Thread: %d", signalToRaise, requestedThreadPtr);

	CW_FREE_OBJECT(a->requestedThreadPtr);
	CW_FREE_OBJECT(a);

	return;
}
示例#18
0
int getMacAddr(int sock, char *interface, unsigned char *macAddr)
{

	struct ifreq ethreq;
	int i;

	memset(&ethreq, 0, sizeof(ethreq));
	strncpy(ethreq.ifr_name, interface, IFNAMSIZ);
	if (ioctl(sock, SIOCGIFHWADDR, &ethreq) == -1) {
		return 0;
	}

	for (i = 0; i < MAC_ADDR_LEN; i++) {
		macAddr[i] = (unsigned char)ethreq.ifr_hwaddr.sa_data[i];
	}
	CWDebugLog("\n");

	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);
	    );
示例#20
0
int CWGetFragmentID()
{

	static int fragID = 0;
	int r;

	if (!CWThreadMutexLock(&gCreateIDMutex)) {

		CWDebugLog("Error Locking a mutex");
	}

	r = fragID;

	if (fragID == CW_MAX_FRAGMENT_ID)
		fragID = 0;
	else
		fragID++;

	CWThreadMutexUnlock(&gCreateIDMutex);
	return r;
}
示例#21
0
unsigned int CWGetSeqNum()
{

	static unsigned int seqNum = 0;
	unsigned int r;

	if (!CWThreadMutexLock(&gCreateIDMutex)) {

		CWDebugLog("Error Locking a mutex");
	}

	r = seqNum;

	if (seqNum == CW_MAX_SEQ_NUM)
		seqNum = 0;
	else
		seqNum++;

	CWThreadMutexUnlock(&gCreateIDMutex);
	return r;
}
示例#22
0
/*
 * Manage Join State.
 */
CWStateTransition CWWTPEnterJoin()
{

	CWTimerID waitJoinTimer;
	int seqNum;
	CWProtocolJoinResponseValues values;
	CWStateTransition state = CW_ENTER_DISCOVERY;
	CWDebugLog("Checking if hostapd is connected...");
	if (gRADIO_MAC[0] == 0xAA){
	CWDebugLog("Waiting for hostapd to connect...");
       	while(gRADIO_MAC[0] == 0xAA) sleep(1);
	}
	else {
	CWDebugLog("Hostapd is connected...");
	}

	CWDebugLog("\n");
	CWDebugLog("######### Join State #########");

	/* reset Join state */
	CWNetworkCloseSocket(gWTPSocket);
#ifndef CW_NO_DTLS
	CWSecurityDestroySession(gWTPSession);
	CWSecurityDestroyContext(gWTPSecurityContext);
#endif
	gWTPSecurityContext = NULL;
	gWTPSession = NULL;

	/* Initialize gACInfoPtr */
	gACInfoPtr = malloc(sizeof(CWACInfoValues));
	gACInfoPtr->ACIPv4ListInfo.ACIPv4ListCount = 0;
	gACInfoPtr->ACIPv4ListInfo.ACIPv4List = NULL;
	gACInfoPtr->ACIPv6ListInfo.ACIPv6ListCount = 0;
	gACInfoPtr->ACIPv6ListInfo.ACIPv6List = NULL;
        CWDebugLog("State is %d", state);

        if (gWTPForceACAddress != NULL) {
                CW_CREATE_OBJECT_ERR(gACInfoPtr, CWACInfoValues, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL);
                    );
示例#23
0
文件: WTP.c 项目: kvjqzx/openCAPWAP
/* 
 * Receive a message, that can be fragmented. This is useful not only for the Join State
 */
CWBool CWReceiveMessage(CWProtocolMessage *msgPtr) {
	CWList fragments = NULL;
	int readBytes;
	char buf[CW_BUFFER_SIZE];
	CWBool dataFlag = CW_FALSE;
	
	CW_REPEAT_FOREVER {
		CW_ZERO_MEMORY(buf, CW_BUFFER_SIZE);
#ifdef CW_NO_DTLS
		char *pkt_buffer = NULL;

		CWLockSafeList(gPacketReceiveList);

		while (CWGetCountElementFromSafeList(gPacketReceiveList) == 0)
			CWWaitElementFromSafeList(gPacketReceiveList);

		pkt_buffer = (char*)CWRemoveHeadElementFromSafeListwithDataFlag(gPacketReceiveList, &readBytes,&dataFlag);

		CWUnlockSafeList(gPacketReceiveList);

		CW_COPY_MEMORY(buf, pkt_buffer, readBytes);
		CW_FREE_OBJECT(pkt_buffer);
#else
		if(!CWSecurityReceive(gWTPSession, buf, CW_BUFFER_SIZE, &readBytes)) {return CW_FALSE;}
#endif

		if(!CWProtocolParseFragment(buf, readBytes, &fragments, msgPtr, &dataFlag, NULL)) {
			if(CWErrorGetLastErrorCode() == CW_ERROR_NEED_RESOURCE) { // we need at least one more fragment
				continue;
			} else { // error
				CWErrorCode error;
				error=CWErrorGetLastErrorCode();
				switch(error)
				{
					case CW_ERROR_SUCCESS: {CWDebugLog("ERROR: Success"); break;}
					case CW_ERROR_OUT_OF_MEMORY: {CWDebugLog("ERROR: Out of Memory"); break;}
					case CW_ERROR_WRONG_ARG: {CWDebugLog("ERROR: Wrong Argument"); break;}
					case CW_ERROR_INTERRUPTED: {CWDebugLog("ERROR: Interrupted"); break;}
					case CW_ERROR_NEED_RESOURCE: {CWDebugLog("ERROR: Need Resource"); break;}
					case CW_ERROR_COMUNICATING: {CWDebugLog("ERROR: Comunicating"); break;}
					case CW_ERROR_CREATING: {CWDebugLog("ERROR: Creating"); break;}
					case CW_ERROR_GENERAL: {CWDebugLog("ERROR: General"); break;}
					case CW_ERROR_OPERATION_ABORTED: {CWDebugLog("ERROR: Operation Aborted"); break;}
					case CW_ERROR_SENDING: {CWDebugLog("ERROR: Sending"); break;}
					case CW_ERROR_RECEIVING: {CWDebugLog("ERROR: Receiving"); break;}
					case CW_ERROR_INVALID_FORMAT: {CWDebugLog("ERROR: Invalid Format"); break;}
					case CW_ERROR_TIME_EXPIRED: {CWDebugLog("ERROR: Time Expired"); break;}
					case CW_ERROR_NONE: {CWDebugLog("ERROR: None"); break;}
				}
				CWDebugLog("~~~~~~");
				return CW_FALSE;
			}
		} else break; // the message is fully reassembled
	}
	
	return CW_TRUE;
}
示例#24
0
CW_THREAD_RETURN_TYPE CWACipc_with_ac_hostapd(void *arg){
	
	int tmp_WTPIndex = -1;
	
	int len;
	int k;
	
	#if defined(LOCALUDP)
		struct sockaddr_un server;
	#else
		#if defined(USEIPV6)
			struct sockaddr_in6 server;
		#else
			struct sockaddr_in server;
		#endif
	#endif

	unsigned char buffer[2048];
	int connect_ret;
	char cmd[10];
	
	CWProtocolMessage* frame=NULL;
	CWNetworkLev4Address address;
	CWThreadSetSignals(SIG_BLOCK, 1, SIGALRM);

    #if defined(LOCALUDP)
		sock = socket(AF_UNIX, SOCK_DGRAM, 0);
	
	#elif defined(NETUDP)
		#if defined(USEIPV6)
			bzero(&server, sizeof(server));
			sock = socket(AF_INET6,SOCK_DGRAM,IPPROTO_UDP);
		#else
			memset(&server, 0, sizeof(server));
			sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
		#endif
		
	#else
		#if defined(USEIPV6)
			bzero(&server, sizeof(server));
			sock = socket(AF_INET6,SOCK_SEQPACKET,IPPROTO_SCTP);
		#else
			memset(&server, 0, sizeof(server));
			sock = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP);
		#endif

	#endif

    if (sock < 0) {
		CWDebugLog("AC ipc HOSTAPD: Error creating socket");
		EXIT_FRAME_THREAD(sock);
    }

  
    CWDebugLog("AC ipc HOSTAPD: Trying to connect to hostapd (AC)...");

	#if defined(LOCALUDP)
		server.sun_family = AF_UNIX;
		strcpy(server.sun_path, gHostapd_unix_path);
		unlink(server.sun_path);
		connect_ret = bind(sock, (struct sockaddr *)&server,  strlen(server.sun_path) + sizeof(server.sun_family));
	
	
    #else
		#if defined(USEIPV6)
			server.sin6_family = AF_INET6;
			server.sin6_port = gHostapd_port;
			server.sin6_addr = in6addr_any;
		#else
			server.sin_family = AF_INET;
			server.sin_port = gHostapd_port;
			server.sin_addr.s_addr = INADDR_ANY;
		#endif
		connect_ret = bind(sock,(struct sockaddr *)&server,sizeof(server));
		
	#endif
    
    if ( connect_ret == -1) {
		CWDebugLog("AC ipc HOSTAPD: Error connect to socket");
		EXIT_FRAME_THREAD(sock);
    }
    
   	#if defined(LOCALUDP)
   		
   	#elif defined(NETUDP)
   	
	#else
		if (listen(sock, CW_MAX_WTP) < 0){
			CWDebugLog("AC ipc HOSTAPD: Error listen ");
			EXIT_FRAME_THREAD(sock);
		}
	#endif


	int i=0;
	CWProtocolMessage *completeMsgPtr = NULL;
	int fragmentsNum = 0;
	CWMultiHomedSocket *sockPtr = &gACSocket;
	int dataSocket=0;

	#if defined(LOCALUDP)
		struct sockaddr_un client_tmp;
		client_tmp.sun_family = AF_UNIX;
	#else
		#if defined(USEIPV6)
			struct sockaddr_in6 client_tmp;
		#else
			struct sockaddr_in client_tmp;
		#endif
	#endif
	
	int address_size_tmp = sizeof(client_tmp);
	

	for(i=0; i<CW_MAX_WTP; i++){
		ch[i].associated = 0;
		#if defined(LOCALUDP)
			ch[i].client.sun_family = AF_UNIX;
			ch[i].address_size = sizeof(struct sockaddr_un);
		#else
			#if defined(USEIPV6)
				ch[i].client.sin6_port = 0;
			#else
				ch[i].client.sin_port = 0;
			#endif
		#endif

	}
	
	#if defined(LOCALUDP)
		CWLog("Accept Packet at pipe: %s",gHostapd_unix_path);
		
	#elif defined(NETUDP) 
		#if defined(USEIPV6)
			CWLog("Accept UDP v6 Packet at Port: %d",server.sin6_port);
		#else
			CWLog("Accept UDP v4 Packet at Port: %d",server.sin_port);
		#endif
		
	#else
		#if defined(USEIPV6)
			CWLog("Accept SCTP v6 Packet at Port: %d",server.sin6_port);
		#else
			CWLog("Accept SCTP v4 Packet at Port: %d",server.sin_port);
		#endif
		
	#endif
	
 	CW_REPEAT_FOREVER {

		tmp_WTPIndex = -1;
		len = recvfrom(sock, buffer, 3000, 0, (struct sockaddr *)&client_tmp, &address_size_tmp); 
		
		#if defined(LOCALUDP)
			sprintf(client_tmp.sun_path, "%s%c%c%c%c%c",server.sun_path, buffer[1],buffer[2],buffer[3],buffer[4],buffer[5]);
		#endif
		
		if(Exist_WTPs()==0){ 
			send_close_cmd(client_tmp,sizeof(client_tmp)); 	
			continue;	
		}

		if(len <= 0 ) { continue;	/* EXIT_FRAME_THREAD(sock) */	}
		
		for( i=0; i<CW_MAX_WTP; i++){
			
			#if defined(LOCALUDP)
					if( strcmp(client_tmp.sun_path,ch[i].client.sun_path)==0 ){
						tmp_WTPIndex = i;
						break;
					}
			#else
				#if defined(USEIPV6)
					if( (client_tmp.sin6_port == ch[i].client.sin6_port) && 
						(strncmp(client_tmp.sin6_addr.s6_addr,ch[i].client.sin6_addr.s6_addr,16)==0 )){
						tmp_WTPIndex = i;
					}
				#else
					if( (client_tmp.sin_port == ch[i].client.sin_port) && 
						(strcmp(inet_ntoa(client_tmp.sin_addr),inet_ntoa(ch[i].client.sin_addr))==0 )){
						tmp_WTPIndex = i;
					}
				#endif			
			#endif

		}
		
		if( tmp_WTPIndex<0 ){// Client not recognized
			
			int wtp_non_associated =  GetWTP_not_associated_to_Hostapd ();
			
			if( wtp_non_associated >= 0){
				
				if( buffer[0]==CONNECT ){
					ch[wtp_non_associated].live = 0;
					ch[wtp_non_associated].start_set_fase = 0;
					ch[wtp_non_associated].associated = 1;
					ch[wtp_non_associated].client = client_tmp;
					ch[wtp_non_associated].address_size = address_size_tmp;
					cmd[0] = CONNECT_R;
					sendto(sock, cmd, 1, 0, (struct sockaddr *)&ch[wtp_non_associated].client, ch[wtp_non_associated].address_size);
					CWLog("wtp_non_associated:%d",wtp_non_associated);
					
					#if defined(LOCALUDP)
						CWLog("Hostapd_AC Connect: %s", ch[wtp_non_associated].client.sun_path);
					#else
						#if defined(USEIPV6)
							CWLog("Hostapd_AC (v6) Connect: %d", ch[wtp_non_associated].client.sin6_port);
						#else
							CWLog("Hostapd_AC (v4) Connect: %s:%d",inet_ntoa(ch[wtp_non_associated].client.sin_addr), ch[wtp_non_associated].client.sin_port);
						#endif					
					#endif

					continue;
					
				}else{
					
					send_close_cmd(client_tmp,sizeof(client_tmp)); 
					continue;
					
				}
				
			}else{
				
				send_close_cmd(client_tmp,sizeof(client_tmp)); 
				continue;
				
			}
			
		}else{ // Client recognized
			int sig_byte = 1;

			#if defined(LOCALUDP)
				sig_byte = 6; //Code
			#endif
			
			if( buffer[0]==DATE_TO_WTP ){
				
				if (gWTPs[tmp_WTPIndex].currentState != CW_ENTER_RUN){
					CWDebugLog("AC %d is not in RUN State. The packet was dropped.",i);
					continue;
				}else if (len > (gWTPs[tmp_WTPIndex].pathMTU-20)){
					CWDebugLog("802.11 data length(%d) > MTU(%d)",len, gWTPs[tmp_WTPIndex].pathMTU);
					continue;
				}else{

					len = len - sig_byte; 

					CW_CREATE_OBJECT_ERR(frame, CWProtocolMessage, return 0;);
					CW_CREATE_PROTOCOL_MESSAGE(*frame, len, return 0;);
					
					memcpy(frame->msg, buffer + sig_byte , len);

					
					frame->offset=len;
					frame->data_msgType = CW_IEEE_802_11_FRAME_TYPE;
						
					if (!CWAssembleDataMessage(&completeMsgPtr, &fragmentsNum, gWTPs[tmp_WTPIndex].pathMTU, frame, NULL, CW_PACKET_PLAIN, 0)){
							for(k = 0; k < fragmentsNum; k++){
								CW_FREE_PROTOCOL_MESSAGE(completeMsgPtr[k]);
							}
							CW_FREE_OBJECT(completeMsgPtr);
							CW_FREE_PROTOCOL_MESSAGE(*frame);
							CW_FREE_OBJECT(frame);
							continue;
					}
						
					for(k = 0; k < sockPtr->count; k++) {
						  if (sockPtr->interfaces[k].sock == gWTPs[tmp_WTPIndex].socket){
						  dataSocket = sockPtr->interfaces[k].dataSock;
						  CW_COPY_NET_ADDR_PTR(&address,&(gWTPs[tmp_WTPIndex].dataaddress));
						  break;
						  }
					}

					if (dataSocket == 0){
						  CWDebugLog("data socket of WTP %d isn't ready.");
						  continue;
					}

					for (k = 0; k < fragmentsNum; k++){
						if(!CWNetworkSendUnsafeUnconnected(	dataSocket, &(address),completeMsgPtr[k].msg,completeMsgPtr[k].offset)){
							CWDebugLog("Failure sending Request");
							break;
						}
					}
					for (k = 0; k < fragmentsNum; k++){
						CW_FREE_PROTOCOL_MESSAGE(completeMsgPtr[k]);
					}
						
					CW_FREE_OBJECT(completeMsgPtr);				
					CW_FREE_PROTOCOL_MESSAGE(*(frame));
					CW_FREE_OBJECT(frame);
				}
				
			}else if( buffer[0]==SET_ADDR ){
示例#25
0
CWBool CWWTPCheckForBindingFrame()
{
	//	
	CWLockSafeList(gFrameList);
	
	while (CWGetCountElementFromSafeList(gFrameList) > 0)
	{
		CWBindingDataListElement* dataFirstElem = CWRemoveHeadElementFromSafeList(gFrameList, NULL);
		if (dataFirstElem)
		{
			int k;
			int fragmentsNum = 0;
			CWProtocolMessage *completeMsgPtr = NULL;
	
			if (!CWAssembleDataMessage(&completeMsgPtr, 
						   &fragmentsNum, 
						   gWTPPathMTU, 
						   dataFirstElem->frame, 
						   dataFirstElem->bindingValues,
#ifdef CW_NO_DTLS
				 		   CW_PACKET_PLAIN
#else
						   (gDtlsSecurity == 1)?CW_PACKET_CRYPT:CW_PACKET_PLAIN           /* 0-CW_PACKET_PLAIN, 1-CW_PACKET_CRYPT */
#endif
						   ))
			{	
				for(k = 0; k < fragmentsNum; k++)
				{
					CW_FREE_PROTOCOL_MESSAGE(completeMsgPtr[k]);
				}
				
				CW_FREE_OBJECT(completeMsgPtr);
				CW_FREE_PROTOCOL_MESSAGE(*(dataFirstElem->frame));
				CW_FREE_OBJECT(dataFirstElem->frame);
				CW_FREE_OBJECT(dataFirstElem->bindingValues);
				CW_FREE_OBJECT(dataFirstElem);
				continue;
			}
								
			for (k = 0; k < fragmentsNum; k++) 
			{

#ifndef CW_NO_DTLS
				if(gDtlsSecurity == 1)
				{
					if (!CWSecuritySend(gWTPSession, completeMsgPtr[k].msg, completeMsgPtr[k].offset))
					{
						CWDebugLog("Failure sending Request");
						break; //gzm break don't unlockSafeList ???
					}
				}
				else
#endif
				{
					if (!CWNetworkSendUnsafeUnconnected(gWTPSocket, &(gACInfoPtr->preferredAddress), completeMsgPtr[k].msg, completeMsgPtr[k].offset))
					{
						CWDebugLog("Failure sending Request");
						break; //gzm break don't unlockSafeList ???
					}
				}
			}
			
			for (k = 0; k < fragmentsNum; k++)
			{
				CW_FREE_PROTOCOL_MESSAGE(completeMsgPtr[k]);
			}
			
			CW_FREE_OBJECT(completeMsgPtr);				
			CW_FREE_PROTOCOL_MESSAGE(*(dataFirstElem->frame));
			CW_FREE_OBJECT(dataFirstElem->frame);
			CW_FREE_OBJECT(dataFirstElem->bindingValues);
			CW_FREE_OBJECT(dataFirstElem);
		}	
	}

	CWUnlockSafeList(gFrameList);	
	
	return CW_TRUE;
}
示例#26
0
CW_THREAD_RETURN_TYPE CWWTPThread_read_data_from_hostapd(void *arg)
{
	/*
	   CWThreadMutexLock(&gRADIO_MAC_mutex);
	   gRADIO_MAC[0]=0xAA;
	   gRADIO_MAC[1]=0xBB;
	   gRADIO_MAC[2]=0xCC;
	   gRADIO_MAC[3]=0xDD;
	   gRADIO_MAC[4]=0xEE;
	   gRADIO_MAC[5]=0xFF;
	   CWThreadMutexUnlock(&gRADIO_MAC_mutex);
	*/
	int len;


#if defined(LOCALUDP)
	struct sockaddr_un server;
#else
#if defined(USEIPV6)
	struct sockaddr_in6 server;
#else
	struct sockaddr_in server;
#endif
#endif

	unsigned char buffer[CW_BUFFER_SIZE];
	int connect_ret;
	unsigned char cmd[10];

	CWProtocolMessage *frame = NULL;
	CWBindingDataListElement *listElement = NULL;

	CWThreadSetSignals(SIG_BLOCK, 1, SIGALRM);

#if defined(LOCALUDP)
	sock = socket(AF_UNIX, SOCK_DGRAM, 0);

#elif defined(NETUDP)
#if defined(USEIPV6)
	bzero(&server, sizeof(server));
	sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
#else
	memset(&server, 0, sizeof(server));
	sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
#endif

#else
#if defined(USEIPV6)
	bzero(&server, sizeof(server));
	sock = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);
#else
	memset(&server, 0, sizeof(server));
	sock = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
#endif

#endif

	if (sock < 0) {
		CWDebugLog("WTP ipc HOSTAPD: Error creating socket");
		EXIT_FRAME_THREAD(sock);
	}

	CWDebugLog("WTP ipc HOSTAPD: Trying to connect to hostapd (wtp)...");

#if defined(LOCALUDP)
	server.sun_family = AF_UNIX;
	strcpy(server.sun_path, gHostapd_unix_path);
	unlink(server.sun_path);

	connect_ret = bind(sock, (struct sockaddr *)&server, strlen(server.sun_path) + sizeof(server.sun_family));

	client.sun_family = AF_UNIX;

#else
#if defined(USEIPV6)
	server.sin6_family = AF_INET6;
	server.sin6_port = gHostapd_port;
	server.sin6_addr = in6addr_any;
#else
	server.sin_family = AF_INET;
	server.sin_port = gHostapd_port;
	server.sin_addr.s_addr = INADDR_ANY;
#endif
	connect_ret = bind(sock, (struct sockaddr *)&server, sizeof(server));

#endif

	if (connect_ret == -1) {
		CWDebugLog("WTP ipc HOSTAPD: Error connect/bind to socket");
		EXIT_FRAME_THREAD(sock);
	}
#if defined(LOCALUDP)

#elif defined(NETUDP)

#else
	/* 1: Only one daemon Hostapd_WTP at time */
	if (listen(sock, 1) < 0) {
		CWDebugLog("WTP ipc HOSTAPD: Error listen ");
		EXIT_FRAME_THREAD(sock);
	}
#endif

#if defined(LOCALUDP)
	CWDebugLog("Waiting packet from Hostapd_WTP at Pipe:%s", gHostapd_unix_path);
#else
	CWDebugLog("Waiting packet from Hostapd_WTP at Port:%d", gHostapd_port);
#endif

        client.sin_family = AF_INET;
        client.sin_addr.s_addr = inet_addr("127.0.0.1");
        client.sin_port = htons(6444);

	address_size = sizeof(client);

	int sig_byte = 1;

#if defined(LOCALUDP)
	sig_byte += 5;
#endif

        CWDebugLog("Checking if hostapd is started already");
        cmd[0] = CONNECT_R;
        sendto(sock, cmd, 1, 0, (struct sockaddr *)&client, address_size);
        cmd[0] = WTPRINFO;      //Next info to get
        sendto(sock, cmd, 1, 0, (struct sockaddr *)&client, address_size);

	CW_REPEAT_FOREVER {

		len = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&client, &address_size);

#if defined(LOCALUDP)
		sprintf(client.sun_path, "%s%c%c%c%c%c", server.sun_path, buffer[1], buffer[2], buffer[3], buffer[4],
			buffer[5]);
#endif

		if (len <= 0) {
			EXIT_FRAME_THREAD(sock)
		}

		if (connected == 0 && buffer[0] != CONNECT && buffer[0] != WTPRINFO_R) {
			CWDebugLog("IPC packet - WTP is not in RUN state");
			CWWTPsend_command_to_hostapd_CLOSE(cmd, 10);
			continue;
		}

		if (buffer[0] == DATE_TO_AC) {

			if (!wtpInRunState)
				continue;

			if (!extract802_11_Frame(&frame, buffer + sig_byte, len - sig_byte)) {
				CWLog("THR FRAME: Error extracting a frame");
				EXIT_FRAME_THREAD(sock);
			}

			CWDebugLog("Send 802.11 management(len:%d) to AC", len - 1);

			CW_CREATE_OBJECT_ERR(listElement, CWBindingDataListElement, EXIT_FRAME_THREAD(sock);
			    );
			listElement->frame = frame;
			listElement->bindingValues = NULL;

			listElement->frame->data_msgType = CW_IEEE_802_11_FRAME_TYPE;

			CWLockSafeList(gFrameList);
			CWAddElementToSafeListTail(gFrameList, listElement, sizeof(CWBindingDataListElement));
			CWUnlockSafeList(gFrameList);

		} else if (buffer[0] == CONNECT) {
示例#27
0
CWBool ACEnterRun(int WTPIndex, CWProtocolMessage *msgPtr, CWBool dataFlag) {

	CWBool toSend = CW_FALSE, timerSet = CW_TRUE;
	CWControlHeaderValues controlVal;
	CWProtocolMessage* messages = NULL;
	int messagesCount = 0;
	unsigned char StationMacAddr[MAC_ADDR_LEN];
	char string[10];
	char socketctl_path_name[50];
	char socketserv_path_name[50];
	msgPtr->offset = 0;

	// cancel NeighborDeadTimer timer
	CWStopNeighborDeadTimer(WTPIndex);
	timerSet = CW_FALSE;

	if (dataFlag) {
		/* We have received a Data Message... now just log this event and do actions by the dataType */
		CWLog("--> Received a DATA Message");

		if (msgPtr->data_msgType == CW_DATA_MSG_FRAME_TYPE) {
			/*Retrive mac address station from msg*/
			memset(StationMacAddr, 0, MAC_ADDR_LEN);
			memcpy(StationMacAddr, msgPtr->msg + SOURCE_ADDR_START, MAC_ADDR_LEN);

			int seqNum = CWGetSeqNum();

			//Send a Station Configuration Request
			if (CWAssembleStationConfigurationRequest(&(gWTPs[WTPIndex].messages),
					&(gWTPs[WTPIndex].messagesCount), gWTPs[WTPIndex].pathMTU, seqNum,
					StationMacAddr)) {

				if (CWACSendAcknowledgedPacket(WTPIndex,
						CW_MSG_TYPE_VALUE_STATION_CONFIGURATION_RESPONSE, seqNum))
					return CW_TRUE;
				else
					CWACStopRetransmission(WTPIndex);
			}
		} else {

			/************************************************************
			 * Update 2009:												*
			 *				Manage special data packets with frequency	*
			 *				statistics informations.					*
			 ************************************************************/

			if (msgPtr->data_msgType == CW_DATA_MSG_FREQ_STATS_TYPE) {

				int cells; /* How many cell are heard */
				int isAck;
				char * freqPayload;
				int socketIndex, indexToSend = htonl(WTPIndex);

				int sizeofAckInfoUnit = CW_FREQ_ACK_SIZE;
				int sizeofFreqInfoUnit = CW_FREQ_CELL_INFO_PAYLOAD_SIZE;
				int sizeOfPayload = 0, payload_offset = 0;

				/*-----------------------------------------------------------------------------------------------
				 *	Payload Management ( infos for frequency application) :
				 *		Ack       Structure : |  WTPIndex  |   Ack Value  | 
				 *      Freq Info Structure : |  WTPIndex  |  Number of cells  |  Frequecies Info Payload | 
				 *-----------------------------------------------------------------------------------------------*/

				memcpy(&isAck, msgPtr->msg, sizeof(int));

				isAck = ntohl(isAck);

				if (isAck == 0) { /* isnt an ack message */
					memcpy(&cells, msgPtr->msg + sizeof(int), sizeof(int));
					cells = ntohl(cells);
					sizeOfPayload = (cells * sizeofFreqInfoUnit) + (2 * sizeof(int));
				} else {
					sizeOfPayload = sizeofAckInfoUnit;
				}

				if ((freqPayload = malloc(sizeOfPayload)) != NULL) {

					memset(freqPayload, 0, sizeOfPayload);
					memcpy(freqPayload, &indexToSend, sizeof(int));
					payload_offset += sizeof(int);

					if (isAck == 0) {
						memcpy(freqPayload + payload_offset, msgPtr->msg + sizeof(int),
								sizeOfPayload - payload_offset);
					} else {
						memcpy(freqPayload + payload_offset, msgPtr->msg + sizeof(int),
								sizeOfPayload - payload_offset);
					}

					socketIndex = gWTPs[WTPIndex].applicationIndex;

					/****************************************************
					 *		Forward payload to correct application 		*
					 ****************************************************/

					if (!CWErr(CWThreadMutexLock(&appsManager.socketMutex[socketIndex]))) {
						CWLog("[ACrunState]:: Error locking socket Application Mutex");
						free(freqPayload);
						return CW_FALSE;
					}

					if (Writen(appsManager.appSocket[socketIndex], freqPayload, sizeOfPayload) < 0) {
						CWThreadMutexUnlock(&appsManager.socketMutex[socketIndex]);
						free(freqPayload);
						CWLog("[ACrunState]:: Error writing Message To Application");
						return CW_FALSE;
					}

					CWThreadMutexUnlock(&appsManager.socketMutex[socketIndex]);
					free(freqPayload);
				} else
					CWLog("[ACrunState]:: Malloc error (payload to frequency application");
			}

			if (msgPtr->data_msgType == CW_DATA_MSG_STATS_TYPE) {
				if (!UnixSocksArray[WTPIndex].data_stats_sock) { //Init Socket only the first time when the function is called
					if ((UnixSocksArray[WTPIndex].data_stats_sock = socket(AF_UNIX, SOCK_DGRAM, 0))
							< 0) {
						CWDebugLog("Error creating socket for data send");
						return CW_FALSE;
					}

					memset(&(UnixSocksArray[WTPIndex].clntaddr), (int) NULL,
							sizeof(UnixSocksArray[WTPIndex].clntaddr));
					UnixSocksArray[WTPIndex].clntaddr.sun_family = AF_UNIX;

					//make unix socket client path name by index i
					snprintf(string, sizeof(string), "%d", WTPIndex);
					string[sizeof(string) - 1] = 0;
					strcpy(socketctl_path_name, SOCKET_PATH_AC);
					strcat(socketctl_path_name, string);
					strcpy(UnixSocksArray[WTPIndex].clntaddr.sun_path, socketctl_path_name);

					unlink(socketctl_path_name);

					memset(&(UnixSocksArray[WTPIndex].servaddr), (int) NULL,
							sizeof(UnixSocksArray[WTPIndex].servaddr));
					UnixSocksArray[WTPIndex].servaddr.sun_family = AF_UNIX;

					//make unix socket server path name by index i
					strcpy(socketserv_path_name, SOCKET_PATH_RECV_AGENT);
					strcat(socketserv_path_name, string);
					strcpy(UnixSocksArray[WTPIndex].servaddr.sun_path, socketserv_path_name);
					CWDebugLog("%s\t%s", socketserv_path_name, socketctl_path_name);
					//fflush(stdout);
				}

				int nbytes;
				int totalBytesToSend = 0;
				bcopy((char*) msgPtr->msg, (char*) &totalBytesToSend, sizeof(unsigned int));
				totalBytesToSend = ntohl(totalBytesToSend);
				int pDataLen = totalBytesToSend; //len of Monitoring Data

				//CWDebugLog("\n%s\t%s", socketserv_path_name, socketctl_path_name);


				CWDebugLog("Total bytes to send %d", totalBytesToSend);

				//Send data stats from AC thread to monitor client over unix socket
				nbytes = sendto(UnixSocksArray[WTPIndex].data_stats_sock, msgPtr->msg, pDataLen, 0,
						(struct sockaddr *) &(UnixSocksArray[WTPIndex].servaddr),
						sizeof(UnixSocksArray[WTPIndex].servaddr));
				if (nbytes < 0) {
					CWDebugLog("Error sending data over socket");
					perror("send error");
					return CW_FALSE;
				}

			}
		}

		return CW_TRUE;
	}

	if (!(CWACParseGenericRunMessage(WTPIndex, msgPtr, &controlVal))) {
		/* Two possible errors: WRONG_ARG and INVALID_FORMAT
		 * In the second case we have an unexpected response: ignore the
		 * message and log the event.
		 */
		return CW_FALSE;
	}

	switch (controlVal.messageTypeValue) {
	case CW_MSG_TYPE_VALUE_CONFIGURE_UPDATE_RESPONSE: {
		CWProtocolResultCode resultCode;
		/*Update 2009:
		 Store Protocol specific response data*/
		CWProtocolVendorSpecificValues* protocolValues = NULL;

		if (!(CWParseConfigurationUpdateResponseMessage(msgPtr, controlVal.msgElemsLen,
				&resultCode, &protocolValues)))
			return CW_FALSE;

		CWACStopRetransmission(WTPIndex);

		if (timerSet) {
			if (!CWRestartNeighborDeadTimer(WTPIndex)) {
				CWDebugLog("CWRestartNeighborDeadTimer returned false");
				CWCloseThread();
			}
		} else {
			if (!CWStartNeighborDeadTimer(WTPIndex)) {
				CWDebugLog("CWStartNeighborDeadTimer returned false");
				CWCloseThread();
			}
		}

		//CWSaveConfigurationUpdateResponseMessage(resultCode, WTPIndex, protocolValues);

		if (resultCode == CW_PROTOCOL_SUCCESS) {
			CWDebugLog("Result Success for Configuration update!!");
			//gWTPs[WTPIndex].isRequestClose = CW_TRUE;
			//CWSignalThreadCondition(&gWTPs[WTPIndex].interfaceWait);
		}

		/*if (gWTPs[WTPIndex].interfaceCommandProgress == CW_TRUE) {
		 CWThreadMutexLock(&gWTPs[WTPIndex].interfaceMutex);
		 gWTPs[WTPIndex].interfaceResult = 1;
		 gWTPs[WTPIndex].interfaceCommandProgress = CW_FALSE;
		 CWSignalThreadCondition(&gWTPs[WTPIndex].interfaceComplete);

		 CWThreadMutexUnlock(&gWTPs[WTPIndex].interfaceMutex);
		 }*/

		break;
	}
	case CW_MSG_TYPE_VALUE_CHANGE_STATE_EVENT_REQUEST: {
		CWProtocolChangeStateEventRequestValues *valuesPtr;

		if (!(CWParseChangeStateEventRequestMessage2(msgPtr, controlVal.msgElemsLen, &valuesPtr)))
			return CW_FALSE;
		if (timerSet) {
			if (!CWRestartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		} else {
			if (!CWStartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		}
		if (!(CWSaveChangeStateEventRequestMessage(valuesPtr, &(gWTPs[WTPIndex].WTPProtocolManager))))
			return CW_FALSE;
		if (!(CWAssembleChangeStateEventResponse(&messages, &messagesCount,
				gWTPs[WTPIndex].pathMTU, controlVal.seqNum)))
			return CW_FALSE;

		toSend = CW_TRUE;
		break;
	}
	case CW_MSG_TYPE_VALUE_ECHO_REQUEST: {
		if (!(CWParseEchoRequestMessage(msgPtr, controlVal.msgElemsLen)))
			return CW_FALSE;
		if (timerSet) {
			if (!CWRestartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		} else {
			if (!CWStartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		}

		if (!(CWAssembleEchoResponse(&messages, &messagesCount, gWTPs[WTPIndex].pathMTU,
				controlVal.seqNum)))
			return CW_FALSE;

		toSend = CW_TRUE;
		break;
	}
	case CW_MSG_TYPE_VALUE_STATION_CONFIGURATION_RESPONSE: {
		CWProtocolResultCode resultCode;
		if (!(CWParseStationConfigurationResponseMessage(msgPtr, controlVal.msgElemsLen,
				&resultCode)))
			return CW_FALSE;
		CWACStopRetransmission(WTPIndex);
		if (timerSet) {
			if (!CWRestartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		} else {
			if (!CWStartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		}
		//CWSaveStationConfigurationResponseMessage(resultCode, WTPIndex);  <-- Must be Implemented ????

		break;
	}
	case CW_MSG_TYPE_VALUE_CLEAR_CONFIGURATION_RESPONSE: {
		CWProtocolResultCode resultCode;
		if (!(CWParseClearConfigurationResponseMessage(msgPtr, controlVal.msgElemsLen, &resultCode)))
			return CW_FALSE;
		CWACStopRetransmission(WTPIndex);
		if (timerSet) {
			if (!CWRestartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		} else {
			if (!CWStartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		}

		if (gWTPs[WTPIndex].interfaceCommandProgress == CW_TRUE) {
			CWThreadMutexLock(&gWTPs[WTPIndex].interfaceMutex);

			gWTPs[WTPIndex].interfaceResult = 1;
			gWTPs[WTPIndex].interfaceCommandProgress = CW_FALSE;
			CWSignalThreadCondition(&gWTPs[WTPIndex].interfaceComplete);

			CWThreadMutexUnlock(&gWTPs[WTPIndex].interfaceMutex);
		}

		break;
	}
	case CW_MSG_TYPE_VALUE_DATA_TRANSFER_REQUEST: {
		CWProtocolWTPDataTransferRequestValues valuesPtr;

		if (!(CWParseWTPDataTransferRequestMessage(msgPtr, controlVal.msgElemsLen, &valuesPtr)))
			return CW_FALSE;
		if (timerSet) {
			if (!CWRestartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		} else {
			if (!CWStartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		}
		if (!(CWAssembleWTPDataTransferResponse(&messages, &messagesCount, gWTPs[WTPIndex].pathMTU,
				controlVal.seqNum)))
			return CW_FALSE;
		toSend = CW_TRUE;
		break;
	}
	case CW_MSG_TYPE_VALUE_WTP_EVENT_REQUEST: {
		CWProtocolWTPEventRequestValues valuesPtr;

		if (!(CWParseWTPEventRequestMessage(msgPtr, controlVal.msgElemsLen, &valuesPtr)))
			return CW_FALSE;
		if (timerSet) {
			if (!CWRestartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		} else {
			if (!CWStartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		}
		if (!(CWSaveWTPEventRequestMessage(&valuesPtr, &(gWTPs[WTPIndex].WTPProtocolManager))))
			return CW_FALSE;

		if (!(CWAssembleWTPEventResponse(&messages, &messagesCount, gWTPs[WTPIndex].pathMTU,
				controlVal.seqNum)))
			return CW_FALSE;

		toSend = CW_TRUE;
		break;
	}
	default:
		/*
		 * We have an unexpected request and we have to send
		 * a corresponding response containing a failure result code
		 */
		CWLog("--> Not valid Request in Run State... we send a failure Response");
		if (timerSet) {
			if (!CWRestartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		} else {
			if (!CWStartNeighborDeadTimer(WTPIndex)) {
				CWCloseThread();
			}
		}
		if (!(CWAssembleUnrecognizedMessageResponse(&messages, &messagesCount,
				gWTPs[WTPIndex].pathMTU, controlVal.seqNum, controlVal.messageTypeValue + 1)))
			return CW_FALSE;

		toSend = CW_TRUE;
		/*return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Message not valid in Run State");*/
	}
	if (toSend) {
		int i;
		CWDebugLog("There is something so send...");

		if (messages == NULL)
			return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL);

		for (i = 0; i < messagesCount; i++) {
#ifdef CW_NO_DTLS
			if(!CWNetworkSendUnsafeUnconnected(gWTPs[WTPIndex].socket,
							&gWTPs[WTPIndex].address,
							messages[i].msg,
							messages[i].offset) ) {
#else
			if (!(CWSecuritySend(gWTPs[WTPIndex].session, messages[i].msg, messages[i].offset))) {
#endif
				CWFreeMessageFragments(messages, messagesCount);
				CW_FREE_OBJECT(messages);
				return CW_FALSE;
			}
		}
		CWFreeMessageFragments(messages, messagesCount);
		CW_FREE_OBJECT(messages);
	}
	gWTPs[WTPIndex].currentState = CW_ENTER_RUN;
	gWTPs[WTPIndex].subState = CW_WAITING_REQUEST;

	CWDebugLog("Coming out of ACEnterRun..");

	return CW_TRUE;
}

CWBool CWACParseGenericRunMessage(int WTPIndex, CWProtocolMessage *msg,
		CWControlHeaderValues* controlVal) {

	if (msg == NULL || controlVal == NULL)
		return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL);

	if (!(CWParseControlHeader(msg, controlVal)))
		/* will be handled by the caller */
		return CW_FALSE;

	/* skip timestamp */
	controlVal->msgElemsLen -= CW_CONTROL_HEADER_OFFSET_FOR_MSG_ELEMS;

	/* Check if it is a request */
	if (controlVal->messageTypeValue % 2 == 1) {

		return CW_TRUE;
	}

	if ((gWTPs[WTPIndex].responseSeqNum != controlVal->seqNum) || (gWTPs[WTPIndex].responseType
			!= controlVal->messageTypeValue)) {

		CWDebugLog("gWTPs: %d\n", gWTPs[WTPIndex].responseSeqNum);
		CWDebugLog("controlVal: %d\n", controlVal->seqNum);
		CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Seq Num or Msg Type not valid!");
		return CW_FALSE;
	}

	return CW_TRUE;
}

/*Update 2009:
 Added vendValues to include a response payload (to pass response data)*/
CWBool CWParseConfigurationUpdateResponseMessage(CWProtocolMessage* msgPtr, int len,
		CWProtocolResultCode* resultCode, CWProtocolVendorSpecificValues** vendValues) {

	int offsetTillMessages;

	if (msgPtr == NULL || resultCode == NULL)
		return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL);
	if ((msgPtr->msg) == NULL)
		return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL);

	offsetTillMessages = msgPtr->offset;

	CWLog("Parsing Configuration Update Response...");

	/* parse message elements */
	while ((msgPtr->offset - offsetTillMessages) < len) {

		unsigned short int elemType = 0;
		unsigned short int elemLen = 0;

		CWParseFormatMsgElem(msgPtr, &elemType, &elemLen);

		switch (elemType) {
		case CW_MSG_ELEMENT_RESULT_CODE_CW_TYPE:
			*resultCode = CWProtocolRetrieve32(msgPtr);
			break;

			/*Update 2009:
			 Added case to implement conf update response with payload*/
		case CW_MSG_ELEMENT_RESULT_CODE_CW_TYPE_WITH_PAYLOAD: {
			int payloadSize = 0;
			CW_CREATE_OBJECT_ERR(*vendValues, CWProtocolVendorSpecificValues, return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL););

			*resultCode = CWProtocolRetrieve32(msgPtr);

			if (CWProtocolRetrieve16(msgPtr) != CW_MSG_ELEMENT_VENDOR_SPEC_PAYLOAD_CW_TYPE)
				/*For now, we only have UCI payloads, so we will accept only vendor payloads for protocol data*/
				return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Unrecognized Message Element in Configuration Update Response");

			(*vendValues)->vendorPayloadType = CWProtocolRetrieve16(msgPtr);

			switch ((*vendValues)->vendorPayloadType) {
			case CW_MSG_ELEMENT_VENDOR_SPEC_PAYLOAD_UCI:
				payloadSize = CWProtocolRetrieve32(msgPtr);
				if (payloadSize != 0) {
					(*vendValues)->payload = (void *) CWProtocolRetrieveStr(msgPtr, payloadSize);
				} else
					(*vendValues)->payload = NULL;
				break;
			case CW_MSG_ELEMENT_VENDOR_SPEC_PAYLOAD_WUM:
				payloadSize = CWProtocolRetrieve32(msgPtr);

				if (payloadSize <= 0) {
					/* Payload can't be zero here,
					 * at least the message type must be specified */
					return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Unrecognized Message Element in Configuration Update Response");
				}
				(*vendValues)->payload = (void *) CWProtocolRetrieveRawBytes(msgPtr, payloadSize);
				break;
			default:
				return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Unrecognized Message Element in Configuration Update Response");
				break;
			}
		}
			break;
		default:
			return CWErrorRaise(CW_ERROR_INVALID_FORMAT, "Unrecognized Message Element in Configuration Update Response");
			break;
		}
	}
示例#28
0
文件: WTP.c 项目: kvjqzx/openCAPWAP
int main (int argc, const char * argv[]) {
	

	/* Daemon Mode */

	pid_t pid;
	
	if (argc <= 1)
		printf("Usage: WTP working_path\n");

	if ((pid = fork()) < 0)
		exit(1);
	else if (pid != 0)
		exit(0);
	else {
		setsid();
		if (chdir(argv[1]) != 0){
			printf("chdir Faile\n");
			exit(1);
		}
		fclose(stdout);
	}	

	
	CWStateTransition nextState = CW_ENTER_DISCOVERY;
	CWLogInitFile(WTP_LOG_FILE_NAME);

#ifndef CW_SINGLE_THREAD
	CWDebugLog("Use Threads");
#else
	CWDebugLog("Don't Use Threads");
#endif
	CWErrorHandlingInitLib();
	if(!CWParseSettingsFile()){
		CWLog("Can't start WTP");
		exit(1);
	}

	/* Capwap receive packets list */
	if (!CWErr(CWCreateSafeList(&gPacketReceiveList)))
	{
		CWLog("Can't start WTP");
		exit(1);
	}

	/* Capwap receive frame list */
	if (!CWErr(CWCreateSafeList(&gFrameList)))
	{
		CWLog("Can't start WTP");
		exit(1);
	}

	CWCreateThreadMutex(&gInterfaceMutex);
	CWSetMutexSafeList(gPacketReceiveList, &gInterfaceMutex);
	CWSetMutexSafeList(gFrameList, &gInterfaceMutex);
	CWCreateThreadCondition(&gInterfaceWait);
	CWSetConditionSafeList(gPacketReceiveList, &gInterfaceWait);
	CWSetConditionSafeList(gFrameList, &gInterfaceWait);

	CWLog("Starting WTP...");
	
	CWRandomInitLib();

	CWThreadSetSignals(SIG_BLOCK, 1, SIGALRM);

	if (timer_init() == 0) {
		CWLog("Can't init timer module");
		exit(1);
	}


#ifdef CW_NO_DTLS
	if( !CWErr(CWWTPLoadConfiguration()) ) {
#else
	if( !CWErr(CWSecurityInitLib())	|| !CWErr(CWWTPLoadConfiguration()) ) {
#endif
		CWLog("Can't start WTP");
		exit(1);
	}

	CWDebugLog("Init WTP Radio Info");
	if(!CWWTPInitConfiguration())
	{
		CWLog("Error Init Configuration");
		exit(1);
	}

#ifdef SOFTMAC
	CWThread thread_ipc_with_wtp_hostapd;
	if(!CWErr(CWCreateThread(&thread_ipc_with_wtp_hostapd, CWWTPThread_read_data_from_hostapd, NULL))) {
		CWLog("Error starting Thread that receive command and 802.11 frame from hostapd (WTP side)");
		exit(1);
	}
#endif


	CWThread thread_receiveFrame;
	if(!CWErr(CWCreateThread(&thread_receiveFrame, CWWTPReceiveFrame, NULL))) {
		CWLog("Error starting Thread that receive binding frame");
		exit(1);
	}


	CWThread thread_receiveStats;
	if(!CWErr(CWCreateThread(&thread_receiveStats, CWWTPReceiveStats, NULL))) {
		CWLog("Error starting Thread that receive stats on monitoring interface");
		exit(1);
	}

	/****************************************
	 * 2009 Update:							*
	 *				Spawn Frequency Stats	*
	 *				Receiver Thread			*
	 ****************************************/

	CWThread thread_receiveFreqStats;
	if(!CWErr(CWCreateThread(&thread_receiveFreqStats, CWWTPReceiveFreqStats, NULL))) {
		CWLog("Error starting Thread that receive frequency stats on monitoring interface");
		exit(1);
	}

	/* if AC address is given jump Discovery and use this address for Joining */
	if(gWTPForceACAddress != NULL)	nextState = CW_ENTER_JOIN;

	/* start CAPWAP state machine */	
	CW_REPEAT_FOREVER {
		switch(nextState) {
			case CW_ENTER_DISCOVERY:
				nextState = CWWTPEnterDiscovery();
				break;
			case CW_ENTER_SULKING:
				nextState = CWWTPEnterSulking();
				break;
			case CW_ENTER_JOIN:
				nextState = CWWTPEnterJoin();
				break;
			case CW_ENTER_CONFIGURE:
				nextState = CWWTPEnterConfigure();
				break;	
			case CW_ENTER_DATA_CHECK:
				nextState = CWWTPEnterDataCheck();
				break;	
			case CW_ENTER_RUN:
				nextState = CWWTPEnterRun();
				break;
			case CW_ENTER_RESET:
				/*
				 * CWStopHeartbeatTimer();
				 * CWStopNeighborDeadTimer();
				 * CWNetworkCloseSocket(gWTPSocket);
				 * CWSecurityDestroySession(gWTPSession);
				 * CWSecurityDestroyContext(gWTPSecurityContext);
				 * gWTPSecurityContext = NULL;
				 * gWTPSession = NULL;
				 */
				nextState = CW_ENTER_DISCOVERY;
				break;
			case CW_QUIT:
				CWWTPDestroy();
				return 0;
		}
	}
}

__inline__ unsigned int CWGetSeqNum() {
	static unsigned int seqNum = 0;
	
	if (seqNum==CW_MAX_SEQ_NUM) seqNum=0;
	else seqNum++;
	return seqNum;
}

__inline__ int CWGetFragmentID() {
	static int fragID = 0;
	return fragID++;
}


/* 
 * Parses config file and inits WTP configuration.
 */
CWBool CWWTPLoadConfiguration() {
	int i;
	
	CWLog("WTP Loads Configuration");
	
	/* get saved preferences */
	if(!CWErr(CWParseConfigFile())) {
		CWLog("Can't Read Config File");
		exit(1);
	}
	
	if(gCWACCount == 0) 
		return CWErrorRaise(CW_ERROR_NEED_RESOURCE, "No AC Configured");
	
	CW_CREATE_ARRAY_ERR(gCWACList, 
			    gCWACCount,
			    CWACDescriptor,
			    return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL););

	for(i = 0; i < gCWACCount; i++) {

		CWDebugLog("Init Configuration for AC at %s", gCWACAddresses[i]);
		CW_CREATE_STRING_FROM_STRING_ERR(gCWACList[i].address, gCWACAddresses[i],
						 return CWErrorRaise(CW_ERROR_OUT_OF_MEMORY, NULL););
	}
示例#29
0
/*
 * 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;
			}
示例#30
0
文件: WTP.c 项目: kvjqzx/openCAPWAP
CWBool CWWTPSendAcknowledgedPacket(int seqNum, 
				   CWList msgElemlist,
				   CWBool (assembleFunc)(CWProtocolMessage **, int *, int, int, CWList),
				   CWBool (parseFunc)(char*, int, int, void*), 
				   CWBool (saveFunc)(void*),
				   void *valuesPtr) {

	CWProtocolMessage *messages = NULL;
	CWProtocolMessage msg;
	int fragmentsNum = 0, i;

	struct timespec timewait;
	
	int gTimeToSleep = gCWRetransmitTimer;
	int gMaxTimeToSleep = CW_ECHO_INTERVAL_DEFAULT/2;

	msg.msg = NULL;
	
	if(!(assembleFunc(&messages, 
			  &fragmentsNum, 
			  gWTPPathMTU, 
			  seqNum, 
			  msgElemlist))) {

		goto cw_failure;
	}
	
	gWTPRetransmissionCount= 0;
	
	while(gWTPRetransmissionCount < gCWMaxRetransmit) 
	{
		CWDebugLog("Transmission Num:%d", gWTPRetransmissionCount);
		for(i = 0; i < fragmentsNum; i++) 
		{
#ifdef CW_NO_DTLS
			if(!CWNetworkSendUnsafeConnected(gWTPSocket, 
							 messages[i].msg,
							 messages[i].offset))
#else
			if(!CWSecuritySend(gWTPSession,
					   messages[i].msg, 
					   messages[i].offset))
#endif
			{
				CWDebugLog("Failure sending Request");
				goto cw_failure;
			}
		}
		
		timewait.tv_sec = time(0) + gTimeToSleep;
		timewait.tv_nsec = 0;

		CW_REPEAT_FOREVER 
		{
			CWThreadMutexLock(&gInterfaceMutex);

			if (CWGetCountElementFromSafeList(gPacketReceiveList) > 0)
				CWErrorRaise(CW_ERROR_SUCCESS, NULL);
			else {
				if (CWErr(CWWaitThreadConditionTimeout(&gInterfaceWait, &gInterfaceMutex, &timewait)))
					CWErrorRaise(CW_ERROR_SUCCESS, NULL);
			}

			CWThreadMutexUnlock(&gInterfaceMutex);

			switch(CWErrorGetLastErrorCode()) {

				case CW_ERROR_TIME_EXPIRED:
				{
					gWTPRetransmissionCount++;
					goto cw_continue_external_loop;
					break;
				}

				case CW_ERROR_SUCCESS:
				{
					/* there's something to read */
					if(!(CWReceiveMessage(&msg))) 
					{
						CW_FREE_PROTOCOL_MESSAGE(msg);
						CWDebugLog("Failure Receiving Response");
						goto cw_failure;
					}
					
					if(!(parseFunc(msg.msg, msg.offset, seqNum, valuesPtr))) 
					{
						if(CWErrorGetLastErrorCode() != CW_ERROR_INVALID_FORMAT) {

							CW_FREE_PROTOCOL_MESSAGE(msg);
							CWDebugLog("Failure Parsing Response");
							goto cw_failure;
						}
						else {
							CWErrorHandleLast();
							{ 
								gWTPRetransmissionCount++;
								goto cw_continue_external_loop;
							}
							break;
						}
					}
					
					if((saveFunc(valuesPtr))) {

						goto cw_success;
					} 
					else {
						if(CWErrorGetLastErrorCode() != CW_ERROR_INVALID_FORMAT) {
							CW_FREE_PROTOCOL_MESSAGE(msg);
							CWDebugLog("Failure Saving Response");
							goto cw_failure;
						} 
					}
					break;
				}

				case CW_ERROR_INTERRUPTED: 
				{
					gWTPRetransmissionCount++;
					goto cw_continue_external_loop;
					break;
				}	
				default:
				{
					CWErrorHandleLast();
					CWDebugLog("Failure");
					goto cw_failure;
					break;
				}
			}
		}
		
		cw_continue_external_loop:
			CWDebugLog("Retransmission time is over");
			
			gTimeToSleep<<=1;
			if ( gTimeToSleep > gMaxTimeToSleep ) gTimeToSleep = gMaxTimeToSleep;
	}

	/* too many retransmissions */
	return CWErrorRaise(CW_ERROR_NEED_RESOURCE, "Peer Dead");
	
cw_success:	
	for(i = 0; i < fragmentsNum; i++) {
		CW_FREE_PROTOCOL_MESSAGE(messages[i]);
	}
	
	CW_FREE_OBJECT(messages);
	CW_FREE_PROTOCOL_MESSAGE(msg);
	
	return CW_TRUE;
	
cw_failure:
	if(messages != NULL) {
		for(i = 0; i < fragmentsNum; i++) {
			CW_FREE_PROTOCOL_MESSAGE(messages[i]);
		}
		CW_FREE_OBJECT(messages);
	}
	CWDebugLog("Failure");
	return CW_FALSE;
}