Initial commit
FossilOrigin-Name: c53d95729c009f8f80a7d63847cef7668ff73f8af0523ab65f7734696f85399c
This commit is contained in:
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();
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user