#include #include #include #include #include #include "wtplist.h" #include "capwap.h" #include "sock.h" #include "socklist.h" #include "conn.h" #include "wtpman.h" #include "conf.h" #include "cw_log.h" #include "dtls.h" #include "conf.h" #include "lwmsg.h" #include #include "capwap.h" #include "cw_util.h" /* macro to convert our client ip to a string */ #define CLIENT_IP (sock_addrtostr((struct sockaddr*)&wtpman->conn->addr, (char[64]){0},64)) ACIPLIST * get_aciplist(); struct ac_info * get_acinfo(); static void wtpman_remove(struct wtpman * wtpman) { wtplist_lock(); wtplist_remove(wtpman); wtplist_unlock(); wtpman_destroy(wtpman); } static void wtpman_run_discovery(void *arg) { struct wtpman * wtpman = (struct wtpman *)arg; struct cwrmsg * cwrmsg; // do { cwrmsg = conn_get_message(wtpman->conn); // }while (!cwrmsg); // printf("cwrmsg = %p\n",cwrmsg); // printf("RID: %d, WBID %d\n",cwrmsg->rid,cwrmsg->wbid); if ( !cwrmsg) { wtpman_remove(wtpman); return; } // printf("cwrmswg type = %08X\n",cwrmsg->type); if (cwrmsg->type==CWMSG_DISCOVERY_REQUEST){ cw_dbg(DBG_CW_MSG,"Received discovery request from %s, seq = %d",CLIENT_IP,cwrmsg->seqnum); process_discovery_request(&wtpman->wtpinfo,cwrmsg->msgelems,cwrmsg->msgelems_len); struct radioinfo radioinfo; radioinfo.rid = cwrmsg->rid; memcpy(radioinfo.rmac, cwrmsg->rmac,8); radioinfo.rmac[0]=0; // cwrmsg->rmac[0]=0; // printf("The RID %d\n",radioinfo.rid); /* int i; for (i=0; i<8; i++){ printf("Rec RMAC: %02x\n",cwrmsg->rmac[i]); } */ // radioinfo.rmac=0; struct ac_info * acinfo = get_acinfo(); char wtpinfostr[8192]; wtpinfo_print(wtpinfostr,&wtpman->wtpinfo); cw_dbg(DBG_CW_INFO,"Discovery request gave us the follwing WTP Info:\n%s",wtpinfostr); // wtpinfo_print(&wtpman->wtpinfo); cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo); //exit(0); } wtpman_remove(wtpman); } /* * Waits for a capwap message until message is received or timeout occurs * Returns NULL if timeout * Returns pointer to cwrms if message is received * Returns EOF in case of any other error */ static struct cwrmsg * wtpman_wait_for_message(struct wtpman * wtpman, time_t timer) { struct cwrmsg * cwrmsg; do { cwrmsg = conn_get_message(wtpman->conn); if (!cwrmsg && wtpman->conn->dtls_error) return EOF; if (!cwrmsg && cw_timer_timeout(timer)) return NULL; }while(!cwrmsg); cw_dbg(DBG_CW_MSG,"Received message from %s, type=%d - %s" ,CLIENT_IP,cwrmsg->type,cw_msgtostr(cwrmsg->type)); return cwrmsg; } static void wtpman_run(void *arg) { struct wtpman * wtpman = (struct wtpman *)arg; struct cwrmsg * cwrmsg = conn_get_message(wtpman->conn); if (socklist[wtpman->socklistindex].type != SOCKLIST_UNICAST_SOCKET){ cw_dbg(DBG_DTLS,"Dropping connection from %s to non-unicast socket", CLIENT_IP); wtpman_remove(wtpman); return; } /* start DTLS handshake */ cw_dbg(DBG_DTLS,"Establishing DTLS session with %s",CLIENT_IP); wtpman->conn->dtls_wait_timer=15; time_t timer = cw_timer_start(wtpman->conn->dtls_wait_timer); wtpman->conn->dtls_cipher=CAPWAP_CIPHER; /* setup DTSL certificates */ int dtls_ok=0; if (conf_sslkeyfilename && conf_sslcertfilename){ wtpman->conn->dtls_key_file = conf_sslkeyfilename; wtpman->conn->dtls_cert_file = conf_sslcertfilename; wtpman->conn->dtls_key_pass = conf_sslkeypass; wtpman->conn->dtls_verify_peer = conf_dtls_verify_peer; dtls_ok=1; } /* setup DTLS psk */ if (conf_dtls_psk){ wtpman->conn->dtls_psk=conf_dtls_psk; wtpman->conn->dtls_psk_len=strlen(conf_dtls_psk); dtls_ok=1; } if (!dtls_ok){ cw_log(LOG_ERR,"Can't establish DTLS session, neither psk nor certs set in config file."); wtpman_remove(wtpman); return; } /* try to accept the connection */ if ( !dtls_accept(wtpman->conn) ){ cw_dbg(DBG_DTLS,"Error establishing DTLS session with %s",CLIENT_IP); wtpman_remove(wtpman); return; } cw_dbg(DBG_DTLS,"DTLS session established with %s, cipher=%s", CLIENT_IP,dtls_get_cipher(wtpman->conn)); /* DTLS handshake done */ /* In join state, wait for join request */ cwrmsg = wtpman_wait_for_message(wtpman,timer); if (!cwrmsg){ cw_dbg(DBG_CW_MSG_ERR,"No join request from %s after %d seconds, WTP died.", sock_addr2str(&wtpman->conn->addr),wtpman->conn->dtls_wait_timer); wtpman_remove(wtpman); return; } if (cwrmsg == EOF){ cw_dbg(DBG_CW_MSG_ERR,"DTLS connection closed while waiting for join request from %s.",CLIENT_IP); wtpman_remove(wtpman); return; } /* the received message MUST be a join request */ if (cwrmsg->type != CWMSG_JOIN_REQUEST){ cw_dbg(DBG_CW_MSG_ERR,"Join request expected from %s, but got %i",CLIENT_IP,cwrmsg->type); wtpman_remove(wtpman); return; } cw_dbg(DBG_CW_MSG,"Received join request from %s",CLIENT_IP); process_join_request(&wtpman->wtpinfo,cwrmsg->msgelems,cwrmsg->msgelems_len); { char wtpinfostr[8192]; wtpinfo_print(wtpinfostr,&wtpman->wtpinfo); cw_dbg(DBG_CW_INFO,"Join request gave us the follwing WTP Info:\n%s",wtpinfostr); } struct radioinfo radioinfo; radioinfo.rid = cwrmsg->rid; memcpy (radioinfo.rmac, cwrmsg->rmac,8); struct ac_info * acinfo = get_acinfo(); // printf("ACN: %s\n",acinfo->ac_name); int result_code = 0; cw_dbg(DBG_CW_MSG,"Sending join response to %s",CLIENT_IP); cwsend_join_response(wtpman->conn,cwrmsg->seqnum,result_code,&radioinfo,acinfo,&wtpman->wtpinfo); cw_log(LOG_INFO,"WTP joined, Name = %s, Location = %s, IP = %s", wtpman->wtpinfo.name,wtpman->wtpinfo.location, sock_addr2str(&wtpman->conn->addr)); /* here the WTP has joined */ cwrmsg = wtpman_wait_for_message(wtpman,timer); if (!cwrmsg){ cw_dbg(DBG_CW_MSG_ERR,"No config or update request from %s after %d seconds, WTP died.", sock_addr2str(&wtpman->conn->addr),wtpman->conn->dtls_wait_timer); wtpman_remove(wtpman); return; } printf("I have got a message of type %d\n",cwrmsg->type); exit(0); // char wtpinfostr[8192]; // wtpinfo_print(wtpinfostr,&wtpman->wtpinfo); // cw_log_debug0("WTP joined\n%s",wtpinfostr); //exit(0); int msg_counter = 0; while(1){ struct cwrmsg * cwrmsg = conn_get_message(wtpman->conn); if (!cwrmsg) { msg_counter++; if (msg_counter < CAPWAP_ECHO_INTERVAL *2 ) continue; cw_log_debug0("WTP died"); wtpman_remove(wtpman); return; } if (cwrmsg->type = CWMSG_CONFIGURATION_STATUS_REQUEST){ process_conf_status_request(&wtpman->wtpinfo,cwrmsg->msgelems,cwrmsg->msgelems_len); { char wtpinfostr[8192]; wtpinfo_print(wtpinfostr,&wtpman->wtpinfo); cw_dbg(DBG_CW_INFO,"Join request gave us the follwing WTP Info:\n%s",wtpinfostr); cwsend_conf_status_response(wtpman->conn,cwrmsg->seqnum,result_code,&radioinfo,acinfo,&wtpman->wtpinfo); } } msg_counter=0; if (cwrmsg->type == CWMSG_ECHO_REQUEST){ cwsend_echo_response(wtpman->conn,cwrmsg->seqnum,wtpman->wtpinfo.radioinfo); } // printf("Got msg: %i\n",cwrmsg->type); } // process_discovery(wtpman,cwrmsg); exit(0); printf("Messag gote ssl\n"); printf("Precdeis sssl\n"); printf ("SEQNUM REC: %i\n",cwrmsg->seqnum); printf("procdis ende\n"); exit(0); while (1) { /* sem_wait(&wtpman->q_sem); int qrpos = wtpman->qrpos+1; if (qrpos==WTPMAN_QSIZE) qrpos=0; wtpman->qrpos=qrpos; uint8_t * packet = wtpman->q[qrpos]+4; int len = *( (uint32_t*)(wtpman->q[qrpos])); */ uint8_t * packet = conn_q_get_packet(wtpman->conn); int len = *( (uint32_t*)(packet)); // conn_process_packet(wtpman->conn,packet+4,len); free(packet); } } void wtpman_destroy(struct wtpman * wtpman) { if ( wtpman->conn) conn_destroy(wtpman->conn); free (wtpman); } struct wtpman * wtpman_create(int socklistindex,struct sockaddr * srcaddr) { struct wtpman * wtpman; wtpman = malloc(sizeof(struct wtpman)); if (!wtpman) return 0; memset (wtpman,0,sizeof(struct wtpman)); int sockfd = socklist[socklistindex].reply_sockfd; // wtpman->conn=conn_create(sockfd,srcaddr,process_discovery,wtpman,100); wtpman->conn=conn_create(sockfd,srcaddr,100); if (!wtpman->conn){ wtpman_destroy(wtpman); return NULL; } return wtpman; } void wtpman_addpacket(struct wtpman * wtpman,uint8_t *packet,int len) { conn_q_add_packet(wtpman->conn,packet,len); } void wtpman_lw_addpacket(struct wtpman *wtpman, uint8_t *packet, int len) { uint8_t * m = packet+12; int l = LWTH_GET_LENGTH(packet+6); uint8_t * msg = packet+12; int msgtype = LWMSG_GET_TYPE(msg); int msglen = LWMSG_GET_LEN(msg); printf ("Type is %d, Len is %d\n",msgtype,msglen); uint8_t * msgdata = LWMSG_GET_DATA(msg); /* int c=0; while (c < msglen){ int eltype = LWMSGELEM_GET_TYPE(data); int ellen = LWMSGELEM_GET_LEN(data); printf ("ELEM TYPE: %d, LEN: %d\n",eltype,ellen); c+=ellen+3; data=data+ellen+3; } */ uint8_t * data; lw_foreach_msgelem(data,msgdata,msglen){ int eltype = LWMSGELEM_GET_TYPE(data); int ellen = LWMSGELEM_GET_LEN(data); uint8_t * eldata = LWMSGELEM_GET_DATA(data); wtpinfo_lwreadelem_wtp_descriptor(&wtpman->wtpinfo,eltype,eldata,ellen); printf ("ELEM TYPE: %d, LEN: %d\n",eltype,ellen); } char wi[4096]; wtpinfo_print(wi,&wtpman->wtpinfo); printf ("WTPINFO: \n%s\n",wi); char buffer[2048]; struct lwmsg lwmsg; lwmsg_init(&lwmsg, buffer,conf_macaddress,LWMSG_DISCOVERY_RESPONSE,conn_get_next_seqnum(wtpman->conn)); conn_send_packet(wtpman->conn,buffer,60); } void wtpman_start(struct wtpman * wtpman,int dtlsmode) { if ( dtlsmode ){ cw_log_debug1("Starting wtpman in dtls mode"); pthread_create (&wtpman->thread, NULL, (void *) &wtpman_run, (void *) wtpman); } else{ cw_log_debug1("Starting wtpman in non-dtls mode"); pthread_create (&wtpman->thread, NULL, (void *) &wtpman_run_discovery, (void *) wtpman); } } void wtpman_lw_start(struct wtpman * wtpman) { }