int join_state(struct conn * conn) { struct wtpinfo * wtpinfo = get_wtpinfo(); struct radioinfo ri; memset(&ri,0,sizeof(ri)); int rc; #ifdef WITH_CW_LOG_DEBUG char str[64]; sock_addrtostr(&conn->addr,str,64); cw_log_debug0("Sending join request to %s",str); #endif printf("Seqnum before = %i\n",conn->seqnum); rc = cwsend_join_request(conn,&ri,wtpinfo); printf("Seqnum after = %i\n",conn->seqnum); struct cwrmsg * cwrmsg = conn_get_message(conn); cw_log_debug0("Received message %i",cwrmsg->seqnum); if (cwrmsg->type != CWMSG_JOIN_RESPONSE || cwrmsg->seqnum != conn->seqnum){ printf("Wrong message\n"); } struct ac_info acinfo; memset(&acinfo,0,sizeof(acinfo)); cwread_join_response(&acinfo,cwrmsg->msgelems,cwrmsg->msgelems_len); acinfo_log(0,&acinfo,"Connectet to the following AC"); }
static int acprint(void *p,void*d) //,int ctr) { ACIP * ip = (ACIP*)d; char str[100]; sock_addrtostr((struct sockaddr*)&ip->ip,str,100); // printf("ACIP: %s\n",str); // printf("CTR: %i\n",ip->wtp_count); return 1; }
int wtpconf_ac_list() { if (conf_ac_list) return 1; int i; int len=0; int bcrc; struct sockaddr_storage bcaddr; bcrc = sock_getifaddr(conf_primary_if,AF_INET,IFF_BROADCAST,(struct sockaddr*)&bcaddr); if (bcrc) len++; int deflen = sizeof(default_ac_list)/sizeof(char*); len += deflen; conf_ac_list = malloc(len*sizeof(char*)); if (!conf_ac_list) return 0; for (i=0; i<deflen; i++){ conf_ac_list[i]=strdup(default_ac_list[i]); if (!conf_ac_list[i]) return 0; } if (bcrc){ char bcstr[100]; sock_addrtostr((struct sockaddr*)&bcaddr,bcstr,100); char * c = strchr(bcstr,':'); *c=0; conf_ac_list[i]=strdup(bcstr); } conf_ac_list_len=len; #ifdef WITH_CW_LOG_DEBUG for (i=0; i<conf_ac_list_len; i++){ cw_log_debug0("Using AC: %s\n",conf_ac_list[i]); } #endif return 1; }
void process_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len) { #ifdef WITH_CW_LOG_DEBUG char str[100]; sock_addrtostr(addr,str,100); cw_log_debug1("Received packet from %s, len = %i, via %s\n",str,len, socklist[index].type==SOCKLIST_UNICAST_SOCKET ? "unicast":"bcast/mcast"); cw_log_debug2_dump(buffer,len,"Packet data for packet, recevied from %s",str); #endif switch (socklist[index].ac_proto){ case AC_PROTO_CAPWAP: process_cw_ctrl_packet(index,addr,buffer,len); return; case AC_PROTO_LWAPP: process_lw_ctrl_packet(index,addr,buffer,len); return; } }
int join(struct sockaddr *sa) { int sockfd; int rc; sockfd = socket(AF_INET,SOCK_DGRAM,0); if (sockfd==-1){ cw_log(LOG_ERR,"Can't create socket: %s\n",strerror(errno)); return -1; } sock_set_recvtimeout(sockfd,1); rc = connect(sockfd,(struct sockaddr*)sa,sock_addrlen((struct sockaddr*)sa)); if (rc<0){ char str[100]; sock_addrtostr(sa,str,100); cw_log(LOG_ERR,"Can't connect to %s: %s\n",str,strerror(errno)); close(sockfd); return -1; } struct conn * conn = get_conn(); conn->sock=sockfd; sock_copyaddr(&conn->addr,sa); #ifdef WITH_DTLS cw_dbg (DBG_DTLS,"Establishing DTLS session with %s",sock_addr2str(sa)); /* #ifdef WITH_CW_LOG_DEBUG { char str[100]; sock_addrtostr(sa,str,100); cw_log_debug0("Establishing DTLS connection to %s",str); } #endif */ if (conf_dtls_psk){ conn->dtls_psk=conf_dtls_psk; conn->dtls_psk_len=strlen(conn->dtls_psk); conn->dtls_cipher=conf_dtls_cipher; } if (conf_sslkeyfilename && conf_sslcertfilename){ conn->dtls_key_file = conf_sslkeyfilename; conn->dtls_cert_file = conf_sslcertfilename; conn->dtls_key_pass = conf_sslkeypass; conn->dtls_cipher=conf_dtls_cipher; } rc = dtls_connect(conn); if (rc!=1){ dtls_shutdown(conn); char str[100]; sock_addrtostr(sa,str,100); cw_log(LOG_ERR,"Cant establish DTLS connection to %s",str); close(sockfd); return 0; } #endif cw_dbg (DBG_DTLS,"DTLS session established with %s, cipher=%s",sock_addr2str(sa),dtls_get_cipher(conn)); exit(0); #ifdef WITH_CW_LOG_DEBUG { char str[100]; sock_addrtostr(sa,str,100); cw_log_debug0("DTLS connection to %s established",str); } #endif join_state(conn); return 1; }
static int do_discover_conn(struct conn * conn,struct discovery_info * di) { rand_sleep(conf_max_discovery_interval); struct wtpinfo * wtpinfo; wtpinfo = get_wtpinfo(); // wtpinfo_print(wtpinfo); // struct timespec tstart,tcur; struct radioinfo ri; memset(&ri,0,sizeof(ri)); ri.rmac[0]=6; ri.rmac[2]=14; ri.rmac[3]=14; ri.rmac[4]=14; ri.rmac[5]=14; ri.rmac[6]=14; ri.rmac[7]=14; #ifdef WITH_CW_LOG_DEBUG char str[100]; sock_addrtostr((struct sockaddr*)&conn->addr,str,100); cw_log_debug0("Sending discovery request to %s",str); #endif int rc; do { rc = cwsend_discovery_request(conn,&ri,wtpinfo); if (rc<0){ if (errno == EINTR) continue; if (errno == EMSGSIZE){ conn->mtu-=4; cw_log_debug2("Setting mtu to %i",conn->mtu); continue; } } break; }while (rc<0); if (rc < 0 ) { char str[100]; sock_addrtostr((struct sockaddr*)&conn->addr,str,100); cw_log(LOG_ERR,"Error sending discovery request to %s: %s",str,strerror(errno)); return 0; } struct connlist * connlist; connlist = connlist_create(30); // clock_gettime(CLOCK_REALTIME,&tstart); // int tstart = time(0); int treset = 0; do { char buf[2048]; int buflen=2048; struct sockaddr_storage sa; socklen_t fromlen=sizeof(struct sockaddr_storage); rc = recvfrom(conn->sock,buf,buflen,0,(struct sockaddr*)&sa,&fromlen); if (rc<0){ if (errno==EINTR) rc=0; if (errno==EAGAIN) rc=0; if (errno==EWOULDBLOCK) rc=0; } if (rc>0) { #ifdef WITH_CW_LOG_DEBUG char str[100]; sock_addrtostr((struct sockaddr*)&sa,str,100); cw_log_debug0("Received packet from %s",str); #endif struct conn * rconn; rconn = connlist_get(connlist,(struct sockaddr*)&sa); if (!rconn){ rconn = conn_create_noq(conn->sock,(struct sockaddr*)&sa); //msg_cb,NULL,0); // rconn->pmsgarg=conn->pmsgarg; rconn->mtu = conn->mtu; rconn->seqnum=conn->seqnum; connlist_add(connlist,rconn); } conn_process_packet(rconn,(uint8_t*)buf,rc,msg_cb,di); } /* reset discovery timer after we have received the first response */ if ( di->response_count == 1 && !treset ){ tstart=time(0); treset=1; } //clock_gettime(CLOCK_REALTIME,&tcur); // printf("TTSub: %i %i\n",time(0)-tstart, conf_discovery_interval); }while(time(0)-tstart < conf_discovery_interval && rc>=0 ); if (rc <0){ char str[100]; sock_addrtostr((struct sockaddr*)&conn->addr,str,100); cw_log(LOG_ERR,"Error sendings discovery request to %s: %s",str,strerror(errno)); } connlist_destroy(connlist); return 1; }
int socklist_add_multicast(const char *addr, const char *port, int ac_proto) { struct addrinfo hints; struct addrinfo *res, *res0; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_family = PF_UNSPEC; hints.ai_flags = AI_PASSIVE; int rc = getaddrinfo(addr, port, &hints, &res0); if (rc != 0) { cw_log(LOG_ERR, "Can't bind multicast address '%s': %s", addr, gai_strerror(rc)); return 0; } for (res = res0; res; res = res->ai_next) { struct sockaddr *sa = res->ai_addr; int sockfd = socket(res->ai_addr->sa_family, SOCK_DGRAM, 0); /* create socket */ if (sockfd == -1) { cw_log(LOG_ERR, "Can't create multicast socket: %", strerror(errno)); continue; } /* bind address */ if (bind(sockfd, sa, sock_addrlen(sa)) < 0) { close(sockfd); cw_log(LOG_ERR, "Can't bind multicast %s: %s", addr, strerror(errno)); continue; } /* use setsockopt() to request that the kernel joins a multicast group */ void *opt; int optlen; if (res->ai_addr->sa_family == AF_INET) { struct ip_mreq mreq; memset(&mreq, 0, sizeof(mreq)); struct sockaddr_in *sain = (struct sockaddr_in *) res->ai_addr; mreq.imr_multiaddr.s_addr = sain->sin_addr.s_addr; mreq.imr_interface.s_addr = htonl(INADDR_ANY); opt = &mreq; optlen = sizeof(mreq); char sinin[100]; sock_addrtostr((struct sockaddr *) sain, sinin, 100,1); if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, opt, optlen) < 0) { close(sockfd); cw_log(LOG_ERR, "Can't add multicast membership %s: %s", addr, strerror(errno)); continue; } } if (res->ai_addr->sa_family == AF_INET6) { struct ipv6_mreq mreq; memset(&mreq, 0, sizeof(mreq)); struct sockaddr_in6 *sain6 = (struct sockaddr_in6 *) res->ai_addr; // mreq.ipv6mr_multiaddr.s_addr=sain->sin_addr.s_addr; memcpy(&mreq.ipv6mr_multiaddr.s6_addr, &sain6->sin6_addr.s6_addr, sizeof(sain6->sin6_addr.s6_addr)); // int si = sizeof(sain6->sin6_addr.s6_addr); // int i = sain6->sin6_addr.s6_addr; mreq.ipv6mr_interface = 0; //htonl(INADDR_ANY); opt = &mreq; optlen = sizeof(mreq); if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, opt, optlen) < 0) { close(sockfd); cw_log(LOG_ERR, "Can't join multicast group %s: %s", addr, strerror(errno)); continue; } } int rfd = find_reply_socket(sa, 0); socklist[socklist_len].sockfd = sockfd; // socklist[socklist_len].reply_sockfd = rfd; socklist[socklist_len].type = SOCKLIST_BCASTMCAST_SOCKET; socklist[socklist_len].family = sa->sa_family; socklist[socklist_len].ac_proto = ac_proto; socklist_len++; cw_log(LOG_INFO, "Bound to multicast group: %s (fd=%i,r:%i)", addr, sockfd, rfd); } freeaddrinfo(res0); return 1; }