예제 #1
0
/**
 * 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;
}
예제 #2
0
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;
}
예제 #3
0
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;


}