Initial commit
FossilOrigin-Name: c53d95729c009f8f80a7d63847cef7668ff73f8af0523ab65f7734696f85399c
This commit is contained in:
		
							
								
								
									
										63
									
								
								src/ac/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/ac/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
ifndef CC
 | 
			
		||||
	CC=gcc
 | 
			
		||||
endif
 | 
			
		||||
SYSARCH := $(shell uname -m)
 | 
			
		||||
ifndef ARCH
 | 
			
		||||
        ARCH=$(SYSARCH)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
LDFLAGS = -g -D_REENTRANT -L/usr/local/lib -L../capwap/$(ARCH) 
 | 
			
		||||
 | 
			
		||||
CFLAGS = -Wall -g -O0 -D_REENTRANT -DCW_NO_DTLS -DIPV6 -I/usr/local/include -I../capwap
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LIBS+=-lcapwap
 | 
			
		||||
LIBS+=-lrt
 | 
			
		||||
LIBS+=-lssl
 | 
			
		||||
LIBS+=-lcrypto
 | 
			
		||||
LIBS+=-lpthread
 | 
			
		||||
LIBS+=-lconfuse
 | 
			
		||||
LIBS+=-lsqlite3
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CFLAGS += -DWITH_CW_LOG
 | 
			
		||||
CFLAGS += -DWITH_CW_LOG_DEBUG
 | 
			
		||||
CFLAGS += -DWITH_RMAC_SUPPORT
 | 
			
		||||
CFLAGS += -DWITH_DTLS
 | 
			
		||||
CFLAGS += -DWITH_IPV6
 | 
			
		||||
 | 
			
		||||
RM = /bin/rm -f 
 | 
			
		||||
 | 
			
		||||
# list of generated object files for AC. 
 | 
			
		||||
AC_OBJS =   wtplist.o wtpman.o conf.o ac_main.o \
 | 
			
		||||
	    ac_interface.o \
 | 
			
		||||
	    socklist.o \
 | 
			
		||||
	    db.o \
 | 
			
		||||
 | 
			
		||||
AC_SRCS = $(AC_OBJS:.o=.c) 
 | 
			
		||||
AC_DEPS := $(AC_OBJS:.o=.d)
 | 
			
		||||
 | 
			
		||||
AC_NAME = actube
 | 
			
		||||
 | 
			
		||||
.PHONY: deps clean clean_libs libs
 | 
			
		||||
 | 
			
		||||
# top-level rule, to compile everything. 
 | 
			
		||||
all: $(AC_NAME) 
 | 
			
		||||
 | 
			
		||||
#$(WTP_NAME) $(WUA_NAME)
 | 
			
		||||
 | 
			
		||||
$(AC_NAME): $(AC_OBJS) 
 | 
			
		||||
	$(CC) $(AC_OBJS) $(CC_FLAGS) $(OPENSSL_INCLUDE) -o $(AC_NAME) $(LDFLAGS) $(LIBS) 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
clean: 
 | 
			
		||||
	$(RM) $(AC_NAME) $(AC_OBJS) $(AC_DEPS)
 | 
			
		||||
 | 
			
		||||
clean_deps:
 | 
			
		||||
	$(AC_DEPS) 
 | 
			
		||||
	
 | 
			
		||||
deps: $(AC_SRC) 
 | 
			
		||||
	$(CC) -MD -E $(AC_SRCS) $(CFLAGS) >/dev/null
 | 
			
		||||
 | 
			
		||||
-include $(AC_DEPS)
 | 
			
		||||
							
								
								
									
										27
									
								
								src/ac/ac.default.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/ac/ac.default.conf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
#
 | 
			
		||||
# Use IPv4 protocol
 | 
			
		||||
#
 | 
			
		||||
# ipv4=true
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Use IPv6 protocol
 | 
			
		||||
#
 | 
			
		||||
# ipv6=true
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Listen addresses
 | 
			
		||||
#
 | 
			
		||||
# listen =
 | 
			
		||||
# listen = 192.168.0.15
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# dtls_psk = 
 | 
			
		||||
#
 | 
			
		||||
# dtls_psk = 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# ac_name
 | 
			
		||||
# The name reported by actube
 | 
			
		||||
#
 | 
			
		||||
# ac_name = AC
 | 
			
		||||
							
								
								
									
										102
									
								
								src/ac/ac_interface.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/ac/ac_interface.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,102 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
 | 
			
		||||
#include "sock.h"
 | 
			
		||||
 | 
			
		||||
#include "socklist.h"
 | 
			
		||||
#include "acinfo.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
 | 
			
		||||
#include "capwap.h"
 | 
			
		||||
 | 
			
		||||
ACIPLIST * get_aciplist()
 | 
			
		||||
{
 | 
			
		||||
	int i=0;
 | 
			
		||||
 | 
			
		||||
	ACIPLIST * aciplist = aciplist_create();
 | 
			
		||||
	if(!aciplist)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	for (i=0; i<socklist_len;i++){
 | 
			
		||||
 | 
			
		||||
		if (socklist[i].type != SOCKLIST_UNICAST_SOCKET)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		struct sockaddr_storage sa;
 | 
			
		||||
		unsigned int salen=sizeof(sa);
 | 
			
		||||
		if ( getsockname(socklist[i].sockfd,(struct sockaddr*)&sa,&salen)<0)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		ACIP * acip;
 | 
			
		||||
		acip = malloc(sizeof(ACIP));
 | 
			
		||||
		if (!acip)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		sock_copyaddr(&acip->ip,(struct sockaddr*)&sa);
 | 
			
		||||
		acip->wtp_count=17;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		aciplist_add(aciplist,acip);
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	return aciplist;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct ac_info * get_acinfo()
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
	struct ac_info * acinfo;
 | 
			
		||||
	acinfo = malloc(sizeof(struct ac_info));
 | 
			
		||||
	if(!acinfo)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	memset(acinfo,0,sizeof(struct ac_info));
 | 
			
		||||
	acinfo->ac_name=conf_acname;
 | 
			
		||||
 | 
			
		||||
	acinfo->stations=10;
 | 
			
		||||
	acinfo->limit=10000;
 | 
			
		||||
	acinfo->active_wtps=10;
 | 
			
		||||
	acinfo->max_wtps=conf_max_wtps;
 | 
			
		||||
	acinfo->rmac=2; /* radio mac not supported */
 | 
			
		||||
 | 
			
		||||
	acinfo->vendor_id=conf_vendor_id;
 | 
			
		||||
	acinfo->hardware_version=(uint8_t*)conf_hardware_version;
 | 
			
		||||
	acinfo->software_version=(uint8_t*)conf_software_version;
 | 
			
		||||
 | 
			
		||||
	if (conf_dtls_psk)
 | 
			
		||||
		acinfo->security|=AC_SECURITY_S;
 | 
			
		||||
 | 
			
		||||
	acinfo->dtls_policy = AC_DTLS_POLICY_C;
 | 
			
		||||
//	acinfo->ac_ips = conf_ac_ips;
 | 
			
		||||
//	acinfo->ac_ips_len=conf_ac_ips_len;
 | 
			
		||||
 | 
			
		||||
//	acinfo->salist=conf_salist;
 | 
			
		||||
//	acinfo->salist_len=conf_salist_len;
 | 
			
		||||
 | 
			
		||||
//	acinfo->salist = conf_ac_ips;
 | 
			
		||||
//	acinfo->salist_len = conf_ac_ips_len;
 | 
			
		||||
 | 
			
		||||
	acinfo->aciplist=get_aciplist();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	return acinfo;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
get_join_result()
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										219
									
								
								src/ac/ac_main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								src/ac/ac_main.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,219 @@
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of actube.
 | 
			
		||||
 | 
			
		||||
    actube is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    libcapwap is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
 | 
			
		||||
#include "actube.h"
 | 
			
		||||
#include "wtplist.h"
 | 
			
		||||
#include "dtls.h"
 | 
			
		||||
#include "cw_log.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "sock.h"
 | 
			
		||||
 | 
			
		||||
#include "socklist.h"
 | 
			
		||||
 | 
			
		||||
int ac_run();
 | 
			
		||||
 | 
			
		||||
int main (int argc, const char * argv[]) 
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	cw_log_name="AC-Tube";
 | 
			
		||||
 | 
			
		||||
	read_config("ac.conf");
 | 
			
		||||
	cw_log_debug_level=conf_debug_level;
 | 
			
		||||
 | 
			
		||||
	test_db();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	cw_log(LOG_INFO,"Starting AC-Tube");
 | 
			
		||||
 | 
			
		||||
#ifdef WITH_DTLS
 | 
			
		||||
	dtls_init();
 | 
			
		||||
#endif	
 | 
			
		||||
	if (!socklist_init())
 | 
			
		||||
		goto errX;
 | 
			
		||||
 | 
			
		||||
	if (!wtplist_init())
 | 
			
		||||
		goto errX;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	int rc = ac_run();
 | 
			
		||||
errX:
 | 
			
		||||
	wtplist_destroy();
 | 
			
		||||
	socklist_destroy();
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void process_ctrl_packet(int  index, struct sockaddr * addr, uint8_t * buffer, int len);
 | 
			
		||||
 | 
			
		||||
int ac_run()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	if (!conf_listen_addrs_len){
 | 
			
		||||
		cw_log(LOG_ERR,"Fatal error: No listen addresses found.");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* it is important to create the unicast sockets first, 
 | 
			
		||||
	 * because when we create the mcast an bcast sockets next 
 | 
			
		||||
	 * we will look for already created sockets to find a
 | 
			
		||||
	 * good unicast reply socket */
 | 
			
		||||
 | 
			
		||||
	int i;
 | 
			
		||||
	for(i=0; i<conf_listen_addrs_len; i++){
 | 
			
		||||
		socklist_add_unicast(conf_listen_addrs[i],conf_control_port);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (socklist_len==0){
 | 
			
		||||
		cw_log(LOG_ERR,"Fatal error: Could not setup any listen socket");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* create multicast sockets */
 | 
			
		||||
	for (i=0; i<conf_mcast_groups_len;i++){
 | 
			
		||||
		socklist_add_multicast(conf_mcast_groups[i],conf_control_port);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* broadcast sockety ipv4 only */
 | 
			
		||||
	for (i=0; i<conf_bcast_addrs_len;i++){
 | 
			
		||||
		socklist_add_broadcast(conf_bcast_addrs[i],conf_control_port);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	while(1){
 | 
			
		||||
 | 
			
		||||
		/* prepare fdset */
 | 
			
		||||
		fd_set fset;
 | 
			
		||||
		int max = 0;
 | 
			
		||||
		FD_ZERO(&fset);
 | 
			
		||||
		for (i=0; i<socklist_len; i++){
 | 
			
		||||
			FD_SET(socklist[i].sockfd,&fset);
 | 
			
		||||
			if (socklist[i].sockfd>max)
 | 
			
		||||
				max=socklist[i].sockfd;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* wait for an event */
 | 
			
		||||
		int n;
 | 
			
		||||
	        while((n=select(max+1, &fset, NULL, NULL, NULL)) < 0) {
 | 
			
		||||
			if (errno != EINTR) 
 | 
			
		||||
				return n;
 | 
			
		||||
 | 
			
		||||
	        }
 | 
			
		||||
 | 
			
		||||
		/* process the received packet */
 | 
			
		||||
		for( i=0; i<socklist_len; i++){
 | 
			
		||||
 | 
			
		||||
			if (!FD_ISSET(socklist[i].sockfd,&fset))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			struct sockaddr_storage srcaddr;
 | 
			
		||||
			socklen_t sockaddrlen;
 | 
			
		||||
 | 
			
		||||
			memset(&srcaddr,0,sizeof(struct sockaddr_storage));
 | 
			
		||||
			sockaddrlen = sizeof(struct sockaddr_storage);
 | 
			
		||||
 | 
			
		||||
			uint8_t buffer[4096];
 | 
			
		||||
			int len = sock_receive(socklist[i].sockfd,
 | 
			
		||||
					buffer, sizeof(buffer),
 | 
			
		||||
					0,
 | 
			
		||||
					(struct sockaddr*)&srcaddr, &sockaddrlen);
 | 
			
		||||
 | 
			
		||||
			process_ctrl_packet(i, (struct sockaddr*)&srcaddr,buffer,len);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* close and free all sockts */
 | 
			
		||||
	for(i=0; i<socklist_len; i++){
 | 
			
		||||
//		close(socklist[i]);
 | 
			
		||||
	}
 | 
			
		||||
	free(socklist);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void process_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len)
 | 
			
		||||
{
 | 
			
		||||
	int sock = socklist[index].reply_sockfd;
 | 
			
		||||
 | 
			
		||||
#ifdef WITH_CW_LOG_DEBUG
 | 
			
		||||
	char str[100];
 | 
			
		||||
	sock_addrtostr(addr,str,100);
 | 
			
		||||
	cw_log_debug0("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	
 | 
			
		||||
 | 
			
		||||
	/* first of all check preamble */
 | 
			
		||||
	int preamble = CWTH_GET_PREAMBLE(buffer);
 | 
			
		||||
 | 
			
		||||
#ifdef WITH_DTLS
 | 
			
		||||
	if (preamble != CAPWAP_PACKET_PREAMBLE && preamble != CAPWAP_DTLS_PACKET_PREAMBLE){
 | 
			
		||||
#else
 | 
			
		||||
	if (preamble != CAPWAP_PACKET_PREAMBLE ){
 | 
			
		||||
#endif
 | 
			
		||||
		cw_log_debug0("Discarding packet, wrong preamble, preamble = 0x%01X",preamble);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wtplist_lock();
 | 
			
		||||
	struct wtpman * wtpman = wtplist_get(addr);
 | 
			
		||||
	if (!wtpman){
 | 
			
		||||
 | 
			
		||||
		wtpman = wtpman_create(index,addr);
 | 
			
		||||
 | 
			
		||||
		if (!wtpman ){
 | 
			
		||||
			cw_log(LOG_ERR,"Error creating wtpman: %s",strerror(errno));
 | 
			
		||||
			wtplist_unlock();
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		if (!wtplist_add(wtpman)){
 | 
			
		||||
			cw_log(LOG_ERR,"Error adding wtpman: Too many wtp connections");
 | 
			
		||||
			wtpman_destroy(wtpman);
 | 
			
		||||
			wtplist_unlock();
 | 
			
		||||
			return;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		wtpman_start(wtpman,preamble & 0xf);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wtpman_addpacket(wtpman,buffer,len);
 | 
			
		||||
	wtplist_unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								src/ac/actube.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/ac/actube.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
 | 
			
		||||
#define AC_MAX_LISTEN_SOCKETS 32
 | 
			
		||||
							
								
								
									
										493
									
								
								src/ac/conf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										493
									
								
								src/ac/conf.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,493 @@
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of actube.
 | 
			
		||||
 | 
			
		||||
    libcapwap is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    libcapwap is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
 | 
			
		||||
#include <confuse.h>
 | 
			
		||||
 | 
			
		||||
#include "capwap.h"
 | 
			
		||||
#include "sock.h"
 | 
			
		||||
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
 | 
			
		||||
#include "cw_log.h"
 | 
			
		||||
#include "cw_util.h"
 | 
			
		||||
 | 
			
		||||
char * conf_acname = NULL; 
 | 
			
		||||
int conf_acname_len = 0;
 | 
			
		||||
 | 
			
		||||
long conf_max_wtps = CONF_DEFAULT_MAXWTPS;
 | 
			
		||||
char * conf_logfilename=CONF_DEFAULT_LOGFILENAME;
 | 
			
		||||
struct sockaddr_storage * conf_salist=NULL;
 | 
			
		||||
 | 
			
		||||
char ** conf_listen_addrs;
 | 
			
		||||
int conf_listen_addrs_len=0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char ** conf_mcast_groups=0;
 | 
			
		||||
int conf_mcast_groups_len=0;
 | 
			
		||||
 | 
			
		||||
char ** conf_bcast_addrs=0;
 | 
			
		||||
int conf_bcast_addrs_len;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct sockaddr_storage * conf_bsalist=NULL;
 | 
			
		||||
 | 
			
		||||
int conf_salist_len=0;
 | 
			
		||||
int conf_bsalist_len=0;
 | 
			
		||||
 | 
			
		||||
struct sockaddr * conf_ac_ips;
 | 
			
		||||
int conf_ac_ips_len;
 | 
			
		||||
 | 
			
		||||
char * conf_sslcertfilename=NULL;
 | 
			
		||||
char * conf_sslkeyfilename=NULL;
 | 
			
		||||
char * conf_dtls_psk=NULL;
 | 
			
		||||
 | 
			
		||||
char * conf_ac_hardware_version=NULL;
 | 
			
		||||
char * conf_ac_software_version=NULL;
 | 
			
		||||
int conf_security=0;
 | 
			
		||||
long conf_vendor_id=CONF_DEFAULT_VENDOR_ID;
 | 
			
		||||
 | 
			
		||||
char * conf_hardware_version;
 | 
			
		||||
char * conf_software_version;
 | 
			
		||||
 | 
			
		||||
int conf_use_loopback = 0;
 | 
			
		||||
 | 
			
		||||
long conf_debug_level=-1;
 | 
			
		||||
 | 
			
		||||
char * conf_db_file =0;
 | 
			
		||||
 | 
			
		||||
int conf_ipv4=1;
 | 
			
		||||
#ifdef WITH_IPV6
 | 
			
		||||
int conf_ipv6=1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char * conf_control_port=0;
 | 
			
		||||
cfg_bool_t conf_ignore_wtp_source_port = cfg_false;
 | 
			
		||||
 | 
			
		||||
static int init_acname()
 | 
			
		||||
{
 | 
			
		||||
	if (conf_acname == NULL){
 | 
			
		||||
		conf_acname=CONF_DEFAULT_ACNAME;
 | 
			
		||||
	}
 | 
			
		||||
	conf_acname_len=strlen(conf_acname);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int init_dtls()
 | 
			
		||||
{
 | 
			
		||||
	if (conf_dtls_psk!=NULL){
 | 
			
		||||
		conf_security=CWACSECURITY_FLAGS_S;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;	
 | 
			
		||||
}	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int init_vendor_id()
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int init_version()
 | 
			
		||||
{
 | 
			
		||||
	if (!conf_hardware_version)
 | 
			
		||||
	{
 | 
			
		||||
		struct utsname u;
 | 
			
		||||
		int rc = uname(&u);
 | 
			
		||||
		if (rc<0)
 | 
			
		||||
			conf_hardware_version=CONF_DEFAULT_HARDWARE_VERSION;
 | 
			
		||||
		else{
 | 
			
		||||
			char str[265];
 | 
			
		||||
			sprintf(str,"%s / %s %s",u.machine,u.sysname,u.release);
 | 
			
		||||
			conf_hardware_version=strdup(str);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!conf_software_version)
 | 
			
		||||
		conf_software_version=CONF_DEFAULT_SOFTWARE_VERSION;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int init_control_port()
 | 
			
		||||
{
 | 
			
		||||
	if (conf_control_port != 0)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	char str[30];
 | 
			
		||||
	sprintf(str,"%d",CONF_DEFAULT_CONTROL_PORT);
 | 
			
		||||
	conf_control_port=(char*)cw_setstr((uint8_t**)&conf_control_port,(uint8_t*)str,strlen(str));
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include <ifaddrs.h>
 | 
			
		||||
 | 
			
		||||
static int init_listen_addrs()
 | 
			
		||||
{
 | 
			
		||||
	if (conf_listen_addrs!=0)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	struct ifaddrs * ifap,*ifa;
 | 
			
		||||
 | 
			
		||||
	int rc = getifaddrs(&ifap);
 | 
			
		||||
	if (rc==-1)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* count the addresses */
 | 
			
		||||
	int ctr=0;
 | 
			
		||||
	for (ifa=ifap; ifa!=0; ifa=ifa->ifa_next){
 | 
			
		||||
		if (ifa->ifa_addr->sa_family==AF_INET && conf_ipv4)
 | 
			
		||||
			ctr++;
 | 
			
		||||
#ifdef WITH_IPV6
 | 
			
		||||
		if (ifa->ifa_addr->sa_family==AF_INET6 && conf_ipv6)
 | 
			
		||||
			ctr++;
 | 
			
		||||
#endif		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	conf_listen_addrs = malloc(sizeof(char*)*ctr);
 | 
			
		||||
	if (!conf_listen_addrs){
 | 
			
		||||
		rc=0;
 | 
			
		||||
		goto errX;
 | 
			
		||||
	}
 | 
			
		||||
	memset(conf_listen_addrs,0,sizeof(char*)*ctr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	ctr=0;
 | 
			
		||||
	/* get the addresses */
 | 
			
		||||
	for (ifa=ifap; ifa!=0; ifa=ifa->ifa_next){
 | 
			
		||||
		char str[100];
 | 
			
		||||
 | 
			
		||||
		if(!conf_use_loopback){
 | 
			
		||||
			if ((ifa->ifa_flags & IFF_LOOPBACK)){
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		if (ifa->ifa_addr->sa_family==AF_INET && conf_ipv4){
 | 
			
		||||
			sock_addrtostr(ifa->ifa_addr,str,100);
 | 
			
		||||
			*strchr(str,':')=0;
 | 
			
		||||
			conf_listen_addrs[ctr]=(char*)cw_setstr((uint8_t**)&conf_listen_addrs[ctr],(uint8_t*)str,strlen(str));
 | 
			
		||||
			if (conf_listen_addrs[ctr])
 | 
			
		||||
				ctr++;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
#ifdef WITH_IPV6
 | 
			
		||||
		if (ifa->ifa_addr->sa_family==AF_INET6 && conf_ipv6){
 | 
			
		||||
			sock_addrtostr(ifa->ifa_addr,str,100);
 | 
			
		||||
			if (strncmp(str,"fe80:",5)==0){
 | 
			
		||||
				strcat(str,"%");
 | 
			
		||||
				strcat(str,ifa->ifa_name);
 | 
			
		||||
			}
 | 
			
		||||
			conf_listen_addrs[ctr]=(char*)cw_setstr((uint8_t**)&conf_listen_addrs[ctr],(uint8_t*)str,strlen(str));
 | 
			
		||||
			if (conf_listen_addrs[ctr])
 | 
			
		||||
				ctr++;
 | 
			
		||||
		}
 | 
			
		||||
#endif		
 | 
			
		||||
	}
 | 
			
		||||
	conf_listen_addrs_len=ctr;
 | 
			
		||||
	rc=1;
 | 
			
		||||
errX:
 | 
			
		||||
	freeifaddrs(ifap);
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static char * conf_default_mcast_groups_ipv4[] = {
 | 
			
		||||
	"224.0.1.140",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef WITH_IPV6
 | 
			
		||||
static char * conf_default_mcast_groups_ipv6[] = {
 | 
			
		||||
/*	"ff01:0:0:0:0:0:0:18c",
 | 
			
		||||
	"ff02:0:0:0:0:0:0:18c%em0",
 | 
			
		||||
	"ff03:0:0:0:0:0:0:18c",
 | 
			
		||||
	"ff04:0:0:0:0:0:0:18c",
 | 
			
		||||
	"ff05:0:0:0:0:0:0:18c",
 | 
			
		||||
	"ff06:0:0:0:0:0:0:18c"
 | 
			
		||||
*/	
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//#include "avltree"
 | 
			
		||||
#include "stravltree.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int add_bcast_addr(void *priv, void * addr)
 | 
			
		||||
{
 | 
			
		||||
	char *s = (char*)addr;
 | 
			
		||||
	conf_bcast_addrs[conf_bcast_addrs_len]=strdup(s);
 | 
			
		||||
	if (conf_bcast_addrs[conf_bcast_addrs_len]!=0)
 | 
			
		||||
		conf_bcast_addrs_len++;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Initialize broadcast addresses (ipv4 only)
 | 
			
		||||
 */
 | 
			
		||||
int init_bcast_addrs()
 | 
			
		||||
{
 | 
			
		||||
	if (conf_bcast_addrs)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (!conf_ipv4)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	struct avltree *t = stravltree_create();
 | 
			
		||||
	if (!t)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* add the default broadast address */
 | 
			
		||||
	stravltree_add(t,"255.255.255.255");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* add all other local broadcast addresses */
 | 
			
		||||
	struct ifaddrs * ifa0,*ifa;
 | 
			
		||||
	int rc = getifaddrs(&ifa0);
 | 
			
		||||
	if (rc==-1)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	for (ifa=ifa0; ifa!=0; ifa=ifa->ifa_next){
 | 
			
		||||
		struct sockaddr * sa;
 | 
			
		||||
		if (!(ifa->ifa_flags & IFF_BROADCAST))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
		if(!conf_use_loopback){
 | 
			
		||||
			if ((ifa->ifa_flags & IFF_LOOPBACK))
 | 
			
		||||
				continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		sa = ifa->ifa_addr;
 | 
			
		||||
		if(sa->sa_family != AF_INET)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		char str[100];
 | 
			
		||||
		if (ifa->ifa_broadaddr){
 | 
			
		||||
			sock_addrtostr(ifa->ifa_broadaddr,str,100);
 | 
			
		||||
			*strchr(str,':')=0;
 | 
			
		||||
			stravltree_add(t,str);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	conf_bcast_addrs=malloc(t->count*sizeof(char*));
 | 
			
		||||
 | 
			
		||||
	stravltree_foreach(t,add_bcast_addr,0,1);
 | 
			
		||||
	stravltree_destroy(t);
 | 
			
		||||
 | 
			
		||||
	freeifaddrs(ifa0);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int init_mcast_groups()
 | 
			
		||||
{
 | 
			
		||||
	if (conf_mcast_groups)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	int n = 0;
 | 
			
		||||
	int n4=0,n6=0;
 | 
			
		||||
	if (conf_ipv4){
 | 
			
		||||
		n4=sizeof(conf_default_mcast_groups_ipv4)/sizeof(char*);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef WITH_IPV6
 | 
			
		||||
	if (conf_ipv6){
 | 
			
		||||
		n6=sizeof(conf_default_mcast_groups_ipv6)/sizeof(char*);
 | 
			
		||||
	}
 | 
			
		||||
#endif	
 | 
			
		||||
	n=n4+n6;
 | 
			
		||||
	if (n==0)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	conf_mcast_groups=malloc(sizeof(char*)*n);
 | 
			
		||||
	if (!conf_mcast_groups)
 | 
			
		||||
		return 0;
 | 
			
		||||
	memset(conf_mcast_groups,0,n*sizeof(char*));
 | 
			
		||||
 | 
			
		||||
	int ctr=0;
 | 
			
		||||
	int i;
 | 
			
		||||
	for(i=0; i<n4; i++){
 | 
			
		||||
		uint8_t *g = (uint8_t*)conf_default_mcast_groups_ipv4[i];
 | 
			
		||||
		conf_mcast_groups[ctr]=(char*)cw_setstr((uint8_t**)&conf_mcast_groups[ctr],g,strlen((char*)g));
 | 
			
		||||
		if (conf_mcast_groups[ctr])
 | 
			
		||||
			ctr++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for(i=0; i<n6; i++){
 | 
			
		||||
		uint8_t *g = (uint8_t*)conf_default_mcast_groups_ipv6[i];
 | 
			
		||||
		conf_mcast_groups[ctr]=(char*)cw_setstr((uint8_t**)&conf_mcast_groups[ctr],g,strlen((char*)g));
 | 
			
		||||
		if (conf_mcast_groups[ctr])
 | 
			
		||||
			ctr++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	conf_mcast_groups_len=n;
 | 
			
		||||
	return 1;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int conf_read_strings( cfg_t * cfg, char * name, char ***dst,int *len)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	int n,i;
 | 
			
		||||
	n = cfg_size(cfg, name);
 | 
			
		||||
	*len=n;
 | 
			
		||||
	if (n==0)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	*dst = malloc(sizeof(char*)*n);
 | 
			
		||||
	if (!*dst)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	for (i=0; i<n; i++) {
 | 
			
		||||
		char * str = cfg_getnstr(cfg,name,i);
 | 
			
		||||
		if (!((*dst)[i]=malloc(strlen(str)+1))) {
 | 
			
		||||
			*len=0;
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		strcpy((*dst)[i],str);
 | 
			
		||||
	}
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int read_config(const char * filename){
 | 
			
		||||
	int i,n;
 | 
			
		||||
 | 
			
		||||
	cfg_opt_t opts[] = {
 | 
			
		||||
		CFG_STR_LIST("listen", "{}", CFGF_NONE),
 | 
			
		||||
		CFG_STR_LIST("mcast_groups", "{}", CFGF_NONE),
 | 
			
		||||
		CFG_STR_LIST("bcast_addrs", "{}", CFGF_NONE),
 | 
			
		||||
		CFG_STR_LIST("ac_ips","{}",CFGF_NONE),
 | 
			
		||||
		CFG_SIMPLE_STR("control_port",&conf_control_port),
 | 
			
		||||
		CFG_SIMPLE_INT("max_wtps",&conf_max_wtps),
 | 
			
		||||
		CFG_SIMPLE_INT("debug_level",&conf_debug_level),
 | 
			
		||||
		CFG_SIMPLE_INT("vendor_id",&conf_vendor_id),
 | 
			
		||||
		CFG_SIMPLE_STR("ac_name",&conf_acname),
 | 
			
		||||
		CFG_SIMPLE_STR("ssl_cert",&conf_sslcertfilename),
 | 
			
		||||
		CFG_SIMPLE_STR("ssl_key",&conf_sslkeyfilename),
 | 
			
		||||
		CFG_SIMPLE_STR("dtls_psk",&conf_dtls_psk),
 | 
			
		||||
//		CFG_SIMPLE_BOOL("ignore_wtp_source_port",&conf_ignore_wtp_source_port),
 | 
			
		||||
		CFG_SIMPLE_BOOL("ipv4",&conf_ipv4),
 | 
			
		||||
		CFG_SIMPLE_BOOL("ipv6",&conf_ipv6),
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		CFG_SIMPLE_STR("db_file",conf_db_file),
 | 
			
		||||
 | 
			
		||||
		CFG_END()
 | 
			
		||||
	};
 | 
			
		||||
	cfg_t *cfg;
 | 
			
		||||
	cfg = cfg_init(opts, 0);
 | 
			
		||||
 | 
			
		||||
	cfg_parse(cfg, filename);
 | 
			
		||||
 | 
			
		||||
	/* read the listen addresses */
 | 
			
		||||
	conf_read_strings(cfg,"listen",&conf_listen_addrs,&conf_listen_addrs_len);
 | 
			
		||||
 | 
			
		||||
	/* read multi cast groups */
 | 
			
		||||
	conf_read_strings(cfg,"mcast_groups",&conf_mcast_groups,&conf_mcast_groups_len);
 | 
			
		||||
 | 
			
		||||
	/* read ipv4 broadcast addresses */
 | 
			
		||||
	conf_read_strings(cfg,"bcast_addrs",&conf_bcast_addrs,&conf_bcast_addrs_len);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	n = cfg_size(cfg, "listen");
 | 
			
		||||
	if (! (conf_salist = malloc(sizeof (struct sockaddr_storage)*n)) )
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (! (conf_listen_addrs=malloc(sizeof(char *)*n)))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	memset(conf_listen_addrs,0,sizeof(char*)*n);
 | 
			
		||||
 | 
			
		||||
	conf_salist_len=n;
 | 
			
		||||
	for (i=0; i<n; i++) {
 | 
			
		||||
		char * str = cfg_getnstr(cfg,"listen",i);
 | 
			
		||||
		if (!(conf_listen_addrs[i]=malloc(strlen(str)+1)))
 | 
			
		||||
				return 0;
 | 
			
		||||
 | 
			
		||||
		strcpy(conf_listen_addrs[i],str);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* read ac_ips */
 | 
			
		||||
	n = cfg_size(cfg, "ac_ips");
 | 
			
		||||
	if (! (conf_ac_ips = malloc(sizeof (struct sockaddr)*n)) )
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	conf_ac_ips_len=n;
 | 
			
		||||
	for (i=0; i<n; i++) {
 | 
			
		||||
		struct sockaddr sa;
 | 
			
		||||
		char * str = cfg_getnstr(cfg,"ac_ips",i);
 | 
			
		||||
		if (sock_strtoaddr ( cfg_getnstr(cfg, "ac_ips", i),&sa))
 | 
			
		||||
			conf_ac_ips[i]=sa;
 | 
			
		||||
		else{
 | 
			
		||||
			perror(str);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	cfg_free(cfg);
 | 
			
		||||
 | 
			
		||||
	if (!init_acname() )
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!init_version())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!init_vendor_id())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (!init_dtls())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (!init_control_port())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	init_listen_addrs();
 | 
			
		||||
	init_mcast_groups();
 | 
			
		||||
	init_bcast_addrs();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void free_config()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										94
									
								
								src/ac/conf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/ac/conf.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of ac.
 | 
			
		||||
 | 
			
		||||
    libcapwap is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    libcapwap is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __CONF_H
 | 
			
		||||
#define __CONF_H
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <confuse.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <net/if.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "capwap.h"
 | 
			
		||||
 | 
			
		||||
#ifndef CONF_DEFAULT_ACNAME
 | 
			
		||||
	#define CONF_DEFAULT_ACNAME "AC"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CONF_DEFAULT_MAXWTPS 
 | 
			
		||||
	#define CONF_DEFAULT_MAXWTPS 200
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CONF_DEFAULT_LOGFILENAME
 | 
			
		||||
	#define CONF_DEFAULT_LOGFILENAME NULL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CONF_DEFAULT_CONFIGFILENAME
 | 
			
		||||
	#define CONF_DEFAULT_CONFIGFILENAME "ac.conf"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CONF_DEFAULT_VENDOR_ID
 | 
			
		||||
	#define CONF_DEFAULT_VENDOR_ID 11591	/* Free Software Foundation */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CONF_DEFAULT_SOFTWARE_VERSION
 | 
			
		||||
	#define CONF_DEFAULT_SOFTWARE_VERSION "AC-Tube 0.01"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CONF_DEFAULT_HARDWARE_VERSION
 | 
			
		||||
	#define CONF_DEFAULT_HARDWARE_VERSION "Linux/X86"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef CONF_DEFAULT_CONTROL_PORT
 | 
			
		||||
	#define	CONF_DEFAULT_CONTROL_PORT CAPWAP_CONTROL_PORT
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern char * conf_acname;
 | 
			
		||||
extern int conf_acname_len;
 | 
			
		||||
extern long conf_max_wtps;
 | 
			
		||||
extern char * conf_logfilename;
 | 
			
		||||
extern struct sockaddr_storage * conf_salist;
 | 
			
		||||
extern int conf_salist_len;
 | 
			
		||||
extern long conf_vendor_id;
 | 
			
		||||
extern char * conf_hardware_version;
 | 
			
		||||
extern char * conf_software_version;
 | 
			
		||||
extern char ** conf_listen_addrs;
 | 
			
		||||
extern int conf_listen_addrs_len;
 | 
			
		||||
 | 
			
		||||
extern struct sockaddr * conf_ac_ips;
 | 
			
		||||
extern int conf_ac_ips_len;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern int read_config(const char * filename);
 | 
			
		||||
extern cfg_bool_t conf_ignore_wtp_source_port;
 | 
			
		||||
extern char * conf_control_port;
 | 
			
		||||
 | 
			
		||||
extern char * conf_dtls_psk;
 | 
			
		||||
 | 
			
		||||
extern char ** conf_mcast_groups;
 | 
			
		||||
extern int conf_mcast_groups_len;
 | 
			
		||||
 | 
			
		||||
extern char ** conf_bcast_addrs;
 | 
			
		||||
extern int conf_bcast_addrs_len;
 | 
			
		||||
 | 
			
		||||
extern long conf_debug_level;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										35
									
								
								src/ac/db.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/ac/db.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
 | 
			
		||||
#include <sqlite3.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void test_db()
 | 
			
		||||
{
 | 
			
		||||
// A prepered statement for fetching tables
 | 
			
		||||
	sqlite3_stmt *stmt;
 | 
			
		||||
//
 | 
			
		||||
// // Create a handle for database connection, create a pointer to sqlite3
 | 
			
		||||
	sqlite3 *handle;
 | 
			
		||||
	int rc = sqlite3_open("ac.sqlite3",&handle);
 | 
			
		||||
 | 
			
		||||
	if ( rc ) 
 | 
			
		||||
	{
 | 
			
		||||
		perror("sqlite");
 | 
			
		||||
		printf("Database failed\n");
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printf ("DB RC: %i\n",rc);
 | 
			
		||||
 | 
			
		||||
	char cmd[100] = "xCREATE TABLE IF NOT EXISTS aclist (uname TEXT PRIMARY KEY,pass TEXT NOT NULL,activated INTEGER)";
 | 
			
		||||
 | 
			
		||||
	rc = sqlite3_exec(handle,cmd,0,0,0);
 | 
			
		||||
 | 
			
		||||
	printf("CT RC: %i\n",rc);
 | 
			
		||||
	const char *em = sqlite3_errmsg(handle);
 | 
			
		||||
	printf("ErrMsg: %s\n",em);
 | 
			
		||||
	return ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										341
									
								
								src/ac/socklist.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								src/ac/socklist.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,341 @@
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of actube.
 | 
			
		||||
 | 
			
		||||
    actube is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    libcapwap is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "cw_log.h"
 | 
			
		||||
#include "sock.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "socklist.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct socklistelem * socklist=0;
 | 
			
		||||
int socklist_len;
 | 
			
		||||
static pthread_mutex_t socklist_mutex;
 | 
			
		||||
static int socklist_wtpcount=0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int socklist_init()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	if (pthread_mutex_init(&socklist_mutex,NULL))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	socklist = malloc(sizeof(struct socklistelem) * SOCKLIST_SIZE);
 | 
			
		||||
	memset(socklist,0,sizeof(struct socklistelem)*SOCKLIST_SIZE);
 | 
			
		||||
	if (!socklist){
 | 
			
		||||
		cw_log(LOG_ERR,"Fatal error while initializing socklist: %s",strerror(errno));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void socklist_lock()
 | 
			
		||||
{
 | 
			
		||||
	pthread_mutex_lock(&socklist_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void socklist_unlock()
 | 
			
		||||
{
 | 
			
		||||
	pthread_mutex_unlock(&socklist_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void socklist_destroy()
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	for(i=0; i<socklist_len; i++){
 | 
			
		||||
		close(socklist[i].sockfd);
 | 
			
		||||
	}
 | 
			
		||||
	free(socklist);
 | 
			
		||||
	socklist=0;
 | 
			
		||||
	pthread_mutex_destroy(&socklist_mutex);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int find_reply_socket(struct sockaddr *sa,int bc)
 | 
			
		||||
{
 | 
			
		||||
	int bestsockfd = -1;
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i=0; i<socklist_len; i++){
 | 
			
		||||
		struct sockaddr_storage sn;
 | 
			
		||||
		memset(&sn,0,sizeof(sn));
 | 
			
		||||
		unsigned int snlen = sizeof(struct sockaddr_storage);
 | 
			
		||||
 | 
			
		||||
		if (getsockname(socklist[i].sockfd,(struct sockaddr*)&sn,&snlen)<0){
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sa->sa_family!=sn.ss_family)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (bestsockfd == -1)
 | 
			
		||||
			bestsockfd = socklist[i].sockfd;
 | 
			
		||||
 | 
			
		||||
		if (!bc)
 | 
			
		||||
			return bestsockfd;
 | 
			
		||||
 | 
			
		||||
		struct sockaddr_storage bcaddr;
 | 
			
		||||
 | 
			
		||||
		if (!sock_getbroadcastaddr((struct sockaddr*)&sn,(struct sockaddr*)&bcaddr))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (sock_cmpaddr((struct sockaddr*)&bcaddr,sa,0))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		bestsockfd = socklist[i].sockfd;
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	}	
 | 
			
		||||
	return bestsockfd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void socklist_add_connection(int index)
 | 
			
		||||
{
 | 
			
		||||
	socklist_lock();
 | 
			
		||||
	socklist[index].wtpcount++;
 | 
			
		||||
	socklist_wtpcount++;
 | 
			
		||||
	socklist_unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void socklist_del_connection(int index)
 | 
			
		||||
{
 | 
			
		||||
	socklist_lock();
 | 
			
		||||
	socklist[index].wtpcount--;
 | 
			
		||||
	socklist_wtpcount--;
 | 
			
		||||
	socklist_unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int socklist_add_multicast(const char * addr, const char * port)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
			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_len++;
 | 
			
		||||
 | 
			
		||||
		cw_log(LOG_INFO,"Bound to multicast group: %s (fd=%i,r:%i)",addr,sockfd,rfd);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	freeaddrinfo(res0);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int socklist_add_unicast(const char *addr, const char * port) 
 | 
			
		||||
{
 | 
			
		||||
	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 unicast socket: %",strerror(errno));
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* bind address */
 | 
			
		||||
		if ( bind(sockfd,sa,sock_addrlen(sa)) < 0) {
 | 
			
		||||
			close(sockfd);
 | 
			
		||||
			cw_log(LOG_ERR,"Can't bind  unicast socket %s: %s",addr,strerror(errno));
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		socklist[socklist_len].sockfd=sockfd;
 | 
			
		||||
		socklist[socklist_len].reply_sockfd=sockfd;
 | 
			
		||||
		socklist[socklist_len].family=sa->sa_family;
 | 
			
		||||
		socklist[socklist_len].type=SOCKLIST_UNICAST_SOCKET;
 | 
			
		||||
	
 | 
			
		||||
		socklist_len++;
 | 
			
		||||
		cw_log(LOG_INFO,"Bound to: %s (%i)\n",addr,sockfd);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	freeaddrinfo(res0);	
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int socklist_add_broadcast(const char *addr, const char * port)
 | 
			
		||||
{
 | 
			
		||||
	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 broadcast address '%s': %s",addr,gai_strerror(rc));
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int sockfd;
 | 
			
		||||
	for(res=res0; res; res=res->ai_next){
 | 
			
		||||
 | 
			
		||||
		struct sockaddr *sa = res->ai_addr;
 | 
			
		||||
		sockfd = socket(res->ai_addr->sa_family, SOCK_DGRAM, 0);
 | 
			
		||||
 | 
			
		||||
		/* create socket */
 | 
			
		||||
		if (sockfd==-1){
 | 
			
		||||
			cw_log(LOG_ERR,"Can't create broadcast socket: %",strerror(errno));
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#ifdef IP_BINDANY
 | 
			
		||||
		struct sockaddr_in * sain = (struct sockaddr_in*)sa;
 | 
			
		||||
		if (sain->sin_addr.s_addr==INADDR_BROADCAST ){
 | 
			
		||||
			int opt=1;
 | 
			
		||||
			if (setsockopt(sockfd, IPPROTO_IP, IP_BINDANY, &opt, sizeof(opt))){
 | 
			
		||||
				cw_log(LOG_ERR,"Can't set sockopt IP_BIND_ANY: %s",strerror(errno));
 | 
			
		||||
				continue;
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
#endif		
 | 
			
		||||
 | 
			
		||||
		/* bind address */
 | 
			
		||||
		if ( bind(sockfd,sa,sock_addrlen(sa)) < 0) {
 | 
			
		||||
			close(sockfd);
 | 
			
		||||
			sockfd=-1;
 | 
			
		||||
			cw_log(LOG_ERR,"Can't bind  broadcast %s: %s",addr,strerror(errno));
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		int rfd = find_reply_socket(sa,1);
 | 
			
		||||
 | 
			
		||||
		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_len++;
 | 
			
		||||
 | 
			
		||||
		cw_log(LOG_INFO,"Bound to broadcast: %s (%i) (R:%i)\n",addr,sockfd,rfd);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	freeaddrinfo(res0);	
 | 
			
		||||
	return 1;	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										51
									
								
								src/ac/socklist.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/ac/socklist.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of actube.
 | 
			
		||||
 | 
			
		||||
    actube is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    libcapwap is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __SOCKLIST_H
 | 
			
		||||
#define __SOCKLIST_H
 | 
			
		||||
 | 
			
		||||
#define SOCKLIST_SIZE 32
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	SOCKLIST_UNICAST_SOCKET,
 | 
			
		||||
	SOCKLIST_BCASTMCAST_SOCKET
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct socklistelem{
 | 
			
		||||
	int sockfd;
 | 
			
		||||
	int reply_sockfd;
 | 
			
		||||
	int type;
 | 
			
		||||
	int family;
 | 
			
		||||
	int wtpcount;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern int socklist_add_multicast(const char * addr, const char * port);
 | 
			
		||||
extern int socklist_add_unicast(const char *addr, const char * port);
 | 
			
		||||
extern int socklist_add_broadcast(const char *addr, const char * port);
 | 
			
		||||
extern int socklist_init();
 | 
			
		||||
extern void socklist_destroy();
 | 
			
		||||
extern struct socklistelem * socklist;
 | 
			
		||||
extern int socklist_len;
 | 
			
		||||
extern void socklist_lock();
 | 
			
		||||
extern void socklist_unlock();
 | 
			
		||||
void socklist_add_connection(int index);
 | 
			
		||||
void socklist_del_connection(int index);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										149
									
								
								src/ac/wtplist.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								src/ac/wtplist.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,149 @@
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of actube.
 | 
			
		||||
 | 
			
		||||
    actube is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    libcapwap is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define MAX_WTPS 200
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "wtplist.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "sock.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "cw_log.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
static struct wtpman ** wtplist = 0;
 | 
			
		||||
static pthread_mutex_t wtplist_mutex;
 | 
			
		||||
 | 
			
		||||
static int max_wtp_connections;
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static struct connlist * connlist;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int wtplist_init()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	connlist  = connlist_create(0);
 | 
			
		||||
	if (!connlist)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wtplist_lock()
 | 
			
		||||
{
 | 
			
		||||
	connlist_lock(connlist);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wtplist_unlock()
 | 
			
		||||
{
 | 
			
		||||
	connlist_unlock(connlist);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void wtplist_destroy()
 | 
			
		||||
{
 | 
			
		||||
	connlist_destroy(connlist);
 | 
			
		||||
 | 
			
		||||
/*	if (wtplist)
 | 
			
		||||
		free (wtplist);
 | 
			
		||||
	pthread_mutex_destroy(&wtplist_mutex);
 | 
			
		||||
*/	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct wtpman * wtplist_get(const struct sockaddr * addr)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	struct conn * conn = connlist_get(connlist,addr);
 | 
			
		||||
	if (!conn)
 | 
			
		||||
		return 0;
 | 
			
		||||
	return conn->data;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i=0; i<max_wtp_connections; i++){
 | 
			
		||||
		if (!wtplist[i])
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if ( sock_cmpaddr(&wtplist[i]->conn->addr,addr,1))
 | 
			
		||||
			continue;
 | 
			
		||||
		struct wtpman * wtpman = wtplist[i];
 | 
			
		||||
		return wtpman;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
*/	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct wtpman * wtplist_add(struct wtpman * wtpman)
 | 
			
		||||
{
 | 
			
		||||
	wtpman->conn->data=wtpman;	
 | 
			
		||||
	return connlist_add(connlist,wtpman->conn);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i=0; i<max_wtp_connections; i++){
 | 
			
		||||
		if (!wtplist[i]){
 | 
			
		||||
			wtplist[i]=wtpman;
 | 
			
		||||
			return wtpman;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void wtplist_remove(struct wtpman * wtpman)
 | 
			
		||||
{
 | 
			
		||||
	connlist_remove(connlist,wtpman->conn);
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	printf("Remove wtpman %p\n",wtpman);
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i=0; i<max_wtp_connections; i++){
 | 
			
		||||
		if (wtplist[i]==wtpman){
 | 
			
		||||
			printf("wtpman removed\n");
 | 
			
		||||
			wtplist[i]=0;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								src/ac/wtplist.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/ac/wtplist.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
#ifndef __WTPLIST_H
 | 
			
		||||
#define __WPTLIST_H
 | 
			
		||||
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
 | 
			
		||||
#include "wtpman.h"
 | 
			
		||||
 | 
			
		||||
extern int wtplist_init();
 | 
			
		||||
extern void wtplist_destroy();
 | 
			
		||||
 | 
			
		||||
extern struct wtpman * wtplist_get(const struct sockaddr * addr);
 | 
			
		||||
extern struct wtpman * wtplist_add(struct wtpman * wtpman);
 | 
			
		||||
extern void wtplist_remove(struct wtpman * wtpman);
 | 
			
		||||
extern void wtplist_lock();
 | 
			
		||||
extern void wtplist_unlock();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										286
									
								
								src/ac/wtpman.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								src/ac/wtpman.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,286 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
 | 
			
		||||
#include "wtplist.h"
 | 
			
		||||
 | 
			
		||||
#include "capwap.h"
 | 
			
		||||
#include "socklist.h"
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "wtpman.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "cw_log.h"
 | 
			
		||||
 | 
			
		||||
#include "dtls.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include "capwap.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ACIPLIST * get_aciplist();
 | 
			
		||||
struct ac_info * get_acinfo();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void process_discovery(struct wtpman * wtpman, struct cwrmsg * cwrmsg)
 | 
			
		||||
//uint8_t * hdr, uint8_t *msg, int len)
 | 
			
		||||
{
 | 
			
		||||
	printf("process_discovery called\n");
 | 
			
		||||
	printf("cwmsg: %p\n",cwrmsg);
 | 
			
		||||
	printf("Message Type: %p\n",&cwrmsg->type);
 | 
			
		||||
	printf("Message Type: %d\n",cwrmsg->type);
 | 
			
		||||
	printf("WBID %d\n",cwrmsg->wbid);
 | 
			
		||||
 | 
			
		||||
	switch (cwrmsg->type){
 | 
			
		||||
		case CWMSG_DISCOVERY_REQUEST:
 | 
			
		||||
			printf ("got a discovery requesti DISC\n");
 | 
			
		||||
			printf("MSGELEMS: %p\n",cwrmsg->msgelems);
 | 
			
		||||
			printf("Seqnum %d\n",cwrmsg->seqnum);
 | 
			
		||||
			printf("RIIIID: %d\n",cwrmsg->rid);
 | 
			
		||||
			struct radioinfo radioinfo;
 | 
			
		||||
			radioinfo.rid = cwrmsg->rid;
 | 
			
		||||
			radioinfo.rmac = cwrmsg->rmac;
 | 
			
		||||
			struct ac_info acinfo;
 | 
			
		||||
//			capwap_init_acinfo(&acinfo);
 | 
			
		||||
			process_discovery_request(&wtpman->wtpinfo,cwrmsg->msgelems,cwrmsg->msgelems_len);
 | 
			
		||||
 | 
			
		||||
			wtpinfo_print(&wtpman->wtpinfo);
 | 
			
		||||
 | 
			
		||||
		//	struct radioinfo radioinfo;
 | 
			
		||||
			cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,&acinfo,&wtpman->wtpinfo);			
 | 
			
		||||
			break;
 | 
			
		||||
		case CWMSG_JOIN_REQUEST:
 | 
			
		||||
			printf ("Join message!!!!!!!!!!!!!!!!\n");
 | 
			
		||||
			process_join_request(&wtpman->wtpinfo,cwrmsg->msgelems,cwrmsg->msgelems_len);
 | 
			
		||||
			wtpinfo_print(&wtpman->wtpinfo);
 | 
			
		||||
 | 
			
		||||
			exit(1);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			printf ("Unknown message\n");
 | 
			
		||||
			exit(1);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if ( !cwrmsg)
 | 
			
		||||
	{
 | 
			
		||||
		wtpman_remove(wtpman);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cwrmsg->type==CWMSG_DISCOVERY_REQUEST){	
 | 
			
		||||
		process_discovery_request(&wtpman->wtpinfo,cwrmsg->msgelems,cwrmsg->msgelems_len);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		struct radioinfo radioinfo;
 | 
			
		||||
		radioinfo.rid = cwrmsg->rid;
 | 
			
		||||
		radioinfo.rmac = cwrmsg->rmac;
 | 
			
		||||
		struct ac_info * acinfo = get_acinfo();
 | 
			
		||||
 | 
			
		||||
//		wtpinfo_print(&wtpman->wtpinfo);
 | 
			
		||||
 | 
			
		||||
		cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo);			
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wtpman_remove(wtpman);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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_log_debug0("Dropping connection to non-unicast socket");
 | 
			
		||||
		wtpman_remove(wtpman);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cw_log_debug0("Establishing DTLS connection");
 | 
			
		||||
#ifdef WITH_DTLS
 | 
			
		||||
 | 
			
		||||
	if (!conf_dtls_psk){
 | 
			
		||||
		cw_log(LOG_ERR,"Cant' establish DTLS connection, no psk set in config file");
 | 
			
		||||
		wtpman_remove(wtpman);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	wtpman->conn->dtls_psk=conf_dtls_psk;
 | 
			
		||||
	wtpman->conn->dtls_psk_len=strlen(conf_dtls_psk);
 | 
			
		||||
	wtpman->conn->dtls_cipher=CAPWAP_CIPHER;
 | 
			
		||||
 | 
			
		||||
	if ( !dtls_accept(wtpman->conn) ){
 | 
			
		||||
		cw_log_debug0("Error establishing DTLS connection");
 | 
			
		||||
		wtpman_remove(wtpman);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
#endif	
 | 
			
		||||
	cw_log_debug0("DTLS Session established with");
 | 
			
		||||
	cwrmsg = conn_get_message(wtpman->conn);
 | 
			
		||||
//	printf("Seqnum: %i\n",cwrmsg->seqnum);
 | 
			
		||||
 | 
			
		||||
	if (cwrmsg->type != CWMSG_JOIN_REQUEST){
 | 
			
		||||
		cw_log_debug0("Join request expected but got %i",cwrmsg->type);
 | 
			
		||||
		wtpman_remove(wtpman);
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	process_join_request(&wtpman->wtpinfo,cwrmsg->msgelems,cwrmsg->msgelems_len);
 | 
			
		||||
 | 
			
		||||
	struct radioinfo radioinfo;
 | 
			
		||||
	radioinfo.rid = cwrmsg->rid;
 | 
			
		||||
	radioinfo.rmac = cwrmsg->rmac;
 | 
			
		||||
	struct ac_info * acinfo = get_acinfo();
 | 
			
		||||
 | 
			
		||||
//	printf("ACN: %s\n",acinfo->ac_name);
 | 
			
		||||
 | 
			
		||||
	int result_code = 1;
 | 
			
		||||
	cwsend_join_response(wtpman->conn,cwrmsg->seqnum,result_code,&radioinfo,acinfo,&wtpman->wtpinfo);
 | 
			
		||||
 | 
			
		||||
	cw_log_debug0("WTP joined");
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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_start(struct wtpman * wtpman,int dtlsmode)
 | 
			
		||||
{
 | 
			
		||||
	if ( dtlsmode )
 | 
			
		||||
		pthread_create (&wtpman->thread, NULL, (void *) &wtpman_run, (void *) wtpman);
 | 
			
		||||
	else
 | 
			
		||||
		pthread_create (&wtpman->thread, NULL, (void *) &wtpman_run_discovery, (void *) wtpman);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								src/ac/wtpman.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/ac/wtpman.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
#ifndef __WTPMAN_H
 | 
			
		||||
#define __WTPMAN_H
 | 
			
		||||
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <semaphore.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
#include "capwap.h"
 | 
			
		||||
#include "fragman.h"
 | 
			
		||||
 | 
			
		||||
#define WTPMAN_QSIZE 1024
 | 
			
		||||
 | 
			
		||||
struct wtpman{
 | 
			
		||||
//	struct sockaddr_storage addr;
 | 
			
		||||
//	int sock;
 | 
			
		||||
	pthread_t thread;
 | 
			
		||||
 | 
			
		||||
	/* packet queue */
 | 
			
		||||
/*	uint8_t * q[WTPMAN_QSIZE];
 | 
			
		||||
	int qrpos;
 | 
			
		||||
	int qwpos;
 | 
			
		||||
	sem_t q_sem;
 | 
			
		||||
*/
 | 
			
		||||
	struct conn * conn;
 | 
			
		||||
 | 
			
		||||
	/* fragment manager */
 | 
			
		||||
//	FRAGMAN * fragman;
 | 
			
		||||
 | 
			
		||||
	/* wtp data */
 | 
			
		||||
	uint8_t * wtp_name;
 | 
			
		||||
	uint8_t * wtp_location;
 | 
			
		||||
	uint8_t * session_id;
 | 
			
		||||
	uint8_t wtp_mactype;
 | 
			
		||||
 | 
			
		||||
	struct wtpinfo wtpinfo;
 | 
			
		||||
 | 
			
		||||
//	pthread_mutex_t add_packet_mutex;
 | 
			
		||||
 | 
			
		||||
	int socklistindex;
 | 
			
		||||
	int connected; 
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wtp{
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//extern void wtpman_run(void *arg);
 | 
			
		||||
extern struct wtpman * wtpman_create();
 | 
			
		||||
 | 
			
		||||
extern struct wtpman * wtpman_create(int socklistindex,struct sockaddr * srcaddr);
 | 
			
		||||
 | 
			
		||||
extern void wtpman_addpacket(struct wtpman * wtpman,uint8_t *packet,int len);
 | 
			
		||||
extern void wtpman_destroy(struct wtpman * wtpman);
 | 
			
		||||
extern void wtpman_start(struct wtpman * wtpman,int dtlsmode);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user