/** * Convert a struct sockaddr int to a human readable string. * @param sa sockaddr to convert * @param s Destination buffer * @param maxlen Size of destination buffer * @param addport If true then the port number wil be added to the output * * Works only for sockaddrs of type AF_INET, AF_INET6, AF_PACKET, AF_LINK. */ char *sock_addrtostr(const struct sockaddr *sa, char *s, size_t maxlen, int addport) { char d[maxlen]; int port; switch (sa->sa_family) { case AF_INET: inet_ntop(AF_INET, &(((struct sockaddr_in *) sa)->sin_addr), d, maxlen); if (addport) { port = ((struct sockaddr_in *) sa)->sin_port; sprintf(s, "%s:%i", d, ntohs(port)); } else sprintf(s, "%s", d); break; case AF_INET6: inet_ntop(AF_INET6, &(((struct sockaddr_in6 *) sa)->sin6_addr), d, maxlen); if (addport) { port = ((struct sockaddr_in6 *) sa)->sin6_port; sprintf(s, "[%s]:%i", d, ntohs(port)); } else sprintf(s, "%s", d); break; #ifdef AF_LINK case AF_LINK: { struct sockaddr_dl *sl = (struct sockaddr_dl *) sa; sock_hwaddrtostr(((uint8_t *) sl->sdl_data) + sl->sdl_nlen, sl->sdl_alen, s, ":"); } break; #endif /* AF_LINLK */ #ifdef AF_PACKET case AF_PACKET: { int i; char *sp = s; struct sockaddr_ll *sl = (struct sockaddr_ll *) sa; for (i = 0; i < sl->sll_halen - 1; i++) { sprintf(sp, "%02X:", sl->sll_addr[i]); sp += 3; } sprintf(sp, "%02X", sl->sll_addr[i]); } break; #endif /* AF_PACKET */ default: strncpy(s, "Unknown AF", maxlen); return NULL; } return s; }
int dtls_gnutls_accept(struct conn *conn) { char sock_buf[SOCK_ADDR_BUFSIZE]; char cookie_buf[SOCK_ADDR_BUFSIZE]; struct dtls_gnutls_data *d; uint8_t buffer[2048]; int tlen, rc; time_t c_timer; int bits; gnutls_datum_t cookie_key; gnutls_dtls_prestate_st prestate; gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE); cw_dbg(DBG_DTLS, "Session cookie for %s generated: %s", sock_addr2str(&conn->addr, sock_buf), sock_hwaddrtostr((uint8_t *) (&cookie_key), sizeof(cookie_key), cookie_buf, "")); memset(&prestate, 0, sizeof(prestate)); tlen = dtls_gnutls_bio_read(conn, buffer, sizeof(buffer)); gnutls_dtls_cookie_send(&cookie_key, &conn->addr, sizeof(conn->addr), &prestate, (gnutls_transport_ptr_t) conn, dtls_gnutls_bio_write); rc = -1; c_timer = cw_timer_start(10); while (!cw_timer_timeout(c_timer)) { tlen = conn_q_recv_packet_peek(conn, buffer, sizeof(buffer)); if (tlen < 0 && errno == EAGAIN) continue; if (tlen < 0) { /* something went wrong, we should log a message */ continue; } rc = gnutls_dtls_cookie_verify(&cookie_key, &conn->addr, sizeof(conn->addr), buffer + 4, tlen - 4, &prestate); if (rc < 0) { cw_dbg(DBG_DTLS, "Cookie couldn't be verified: %s", gnutls_strerror(rc)); dtls_gnutls_bio_read(conn, buffer, sizeof(buffer)); continue; } break; } if (rc < 0) { cw_log(LOG_ERR, "Cookie couldn't be verified: %s", gnutls_strerror(rc)); return 0; } cw_dbg(DBG_DTLS, "Cookie verified! Starting handshake with %s ...", sock_addr2str(&conn->addr, sock_buf)); d = dtls_gnutls_data_create(conn, GNUTLS_SERVER | GNUTLS_DATAGRAM); if (!d) return 0; if (conn->dtls_psk_enable) { gnutls_psk_server_credentials_t cred; rc = gnutls_psk_allocate_server_credentials(&cred); if (rc != 0) { cw_log(LOG_ERR,"gnutls_psk_allocate_server_credentials() failed."); } /* GnuTLS will call psk_creds to ask for the key associated with the client's username.*/ gnutls_psk_set_server_credentials_function(cred, psk_creds); /* // Pass the "credentials" to the GnuTLS session. GnuTLS does NOT make an // internal copy of the information, so we have to keep the 'cred' structure // in memory (and not modify it) until we're done with this session.*/ rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, cred); if (rc != 0) { cw_log(LOG_ERR,"gnutls_credentials_set() failed.\n"); } } /* Generate Diffie-Hellman parameters - for use with DHE * kx algorithms. When short bit length is used, it might * be wise to regenerate parameters often. */ /*bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); */ bits = conn->dtls_dhbits; gnutls_dh_params_init(&d->dh_params); cw_dbg(DBG_DTLS, "Generating DH params, %d", bits); gnutls_dh_params_generate2(d->dh_params, bits); cw_dbg(DBG_DTLS, "DH params generated, %d", bits); gnutls_certificate_set_dh_params(d->x509_cred, d->dh_params); gnutls_certificate_server_set_request(d->session, GNUTLS_CERT_REQUEST); gnutls_dtls_prestate_set(d->session, &prestate); c_timer = cw_timer_start(10); do { rc = gnutls_handshake(d->session); } while (!cw_timer_timeout(c_timer) && rc == GNUTLS_E_AGAIN); if (rc < 0) { cw_log(LOG_ERR, "Error in handshake with %s: %s", sock_addr2str(&conn->addr, sock_buf), gnutls_strerror(rc)); return 0; } cw_dbg(DBG_DTLS, "Handshake with %s successful.", sock_addr2str(&conn->addr, sock_buf)); conn->dtls_data = d; conn->read = dtls_gnutls_read; conn->write = dtls_gnutls_write; return 1; }
int wtpinfo_print(char *str, struct wtpinfo * wtpinfo) { char hstr[64]; char *s = str; s+=sprintf (s,"\tWTP Name: %s\n", (!wtpinfo->name ? (uint8_t*)"Not set" : wtpinfo->name) ); s+=sprintf (s,"\tLocation: %s\n", (!wtpinfo->location ? (uint8_t*)"Not set" : wtpinfo->location) ); s+=sprintf (s,"\tMAC Adress: "); if (wtpinfo->macaddress){ sock_hwaddrtostr(wtpinfo->macaddress,wtpinfo->macaddress_len,hstr,":"); s+=sprintf(s,"%s\n",hstr); } else s+=sprintf(s,"Not set\n"); char disctypestr[32]; switch(wtpinfo->discovery_type){ case CW_DISCOVERY_TYPE_STATIC: sprintf(disctypestr,"Static"); break; case CW_DISCOVERY_TYPE_DHCP: sprintf(disctypestr,"DHCP"); break; case CW_DISCOVERY_TYPE_DNS: sprintf(disctypestr,"DNS"); break; case CW_DISCOVERY_TYPE_AC_REFERRAL: sprintf(disctypestr,"AC Referral"); break; default: sprintf(disctypestr,"Unknown"); break; } s+=sprintf (s,"\tDiscovery Type: %s\n",disctypestr); // sock_addrtostr((struct sockaddr*)&wtpinfo->local_ip,hstr,64); /* int i0; for (i0=0; i0<10; i0++){ printf("%d\n", ((char*)(&wtpinfo->local_ip))[i0] ); } */ s+=sprintf (s,"\tLocal IP: %s\n",sock_addr2str(&(wtpinfo->local_ip))); s+=sprintf (s,"\tVendor ID: %d, %s\n", wtpinfo->vendor_id,lw_vendor_id_to_str(wtpinfo->vendor_id) ); s+=sprintf (s,"\tModel No.: "); //, (!wtpinfo->model_no ? (uint8_t*)"Not set" : wtpinfo->model_no) ); s+=bstr_to_str(s,wtpinfo->model_no,0); s+=sprintf(s,"\n"); // s+=sprintf (s,"\tSerial No.: %s\n", (!wtpinfo->serial_no ? (uint8_t*)"Not set" : wtpinfo->serial_no) ); s+=sprintf (s,"\tSerial No.: "); s+=bstr_to_str(s,wtpinfo->serial_no,0); s+=sprintf(s,"\n"); s+=sprintf (s,"\tBoard ID: "); s+=bstr_to_str(s,wtpinfo->board_id,0); s+=sprintf(s,"\n"); s+=sprintf (s,"\tBoard Revision: "); s+=bstr_to_str(s,wtpinfo->board_revision,0); s+=sprintf(s,"\n"); // s+=sprintf (s,"\tBoard Id: %s\n", (!wtpinfo->board_id ? (uint8_t*)"Not set" : wtpinfo->board_id) ); s+=sprintf (s,"\tSoftware Version: "); // s+=version_print(s,wtpinfo->software_version,wtpinfo->software_version_len,wtpinfo->software_vendor_id); s+=cw_format_version(s,wtpinfo->software_version,wtpinfo->software_vendor_id,"Not set"); s+=sprintf (s,"\n"); s+=sprintf (s,"\tHardware Version: "); s+=version_print(s,wtpinfo->hardware_version,wtpinfo->hardware_version_len,wtpinfo->hardware_vendor_id); s+=sprintf (s,"\tBootloader Version: "); s+=version_print(s,wtpinfo->bootloader_version,wtpinfo->bootloader_version_len,wtpinfo->bootloader_vendor_id); //, (!wtpinfo->software_version ? (uint8_t*)"Not set" : wtpinfo->software_version) ); // s+=sprintf (s,"\tHardware Version: %s\n", (!wtpinfo->hardware_version ? (uint8_t*)"Not set" : wtpinfo->hardware_version) ); s+=sprintf (s,"\tMax Radios: %d\n",wtpinfo->max_radios); s+=sprintf (s,"\tRadios in use: %d\n",wtpinfo->radios_in_use); s+=sprintf (s,"\tSession ID: "); if (wtpinfo->session_id) { int i; for (i=0; i<bstr_len(wtpinfo->session_id); i++) s+=sprintf(s,"%02X",bstr_data(wtpinfo->session_id)[i]); } else s+=sprintf(s,"Not set"); s+=sprintf(s,"\n"); s+=sprintf (s,"\tMAC Type: "); switch (wtpinfo->mac_type){ case WTP_MAC_TYPE_LOCAL: s+=sprintf(s,"local"); break; case WTP_MAC_TYPE_SPLIT: s+=sprintf(s,"split"); break; case WTP_MAC_TYPE_BOTH: s+=sprintf(s,"local, split"); break; } s+=sprintf(s,"\n"); s+=sprintf (s,"\tFrame Tunnel Mode: "); s+=sprintf(s,"(%08X)",wtpinfo->frame_tunnel_mode); char * c=""; if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_N){ s+=printf (s,"%snative",c);c=", "; } if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_E){ s+=sprintf (s,"%s802.3",c);c=", "; } if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_L){ s+=sprintf (s,"%sLocal bridging",c);c=", "; } if (wtpinfo->frame_tunnel_mode == 0) s+=sprintf(s," None"); s+=sprintf(s,"\n"); s+=sprintf(s,"\tRadios: %d\n",wtpinfo->max_radios); int i; char ristr[2048]; char *r = ristr; for (i=0; i<wtpinfo->max_radios; i++){ if (wtpinfo->radioinfo[i].set) r+=radioinfo_print(r,&wtpinfo->radioinfo[i]); } s+=sprintf(s,"%s",ristr); s+=sprintf(s,"Encryption: %08x\n",wtpinfo->encryption_cap); s+=wtp_reboot_statistics_print(s,&wtpinfo->reboot_statistics); return s-str; }