Compare commits
	
		
			48 Commits
		
	
	
		
			shell
			...
			b292b88d49
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b292b88d49 | |||
| 97533f67cc | |||
| 259c6c5e66 | |||
| bc5dea6016 | |||
| ec6809b552 | |||
| 1297c46a15 | |||
| cc257ed27f | |||
| 059c0e542e | |||
| 9d3fa452aa | |||
| 300b737efd | |||
| 085e657c76 | |||
| f62b1c56e1 | |||
| acc7b692ee | |||
| 8a8381731f | |||
| 6f4ba62080 | |||
| 0eb3e16932 | |||
| ca4a6b9996 | |||
| 66db979fdb | |||
| 0078c07e58 | |||
| 20bd835f63 | |||
| 1e8b52fd03 | |||
| 2f1985b821 | |||
| 27506fa788 | |||
| 5ed35979cd | |||
| 2064f7dba1 | |||
| 190c94ded4 | |||
| 4fe2bae7f7 | |||
| 89e7e61e1d | |||
| 2b055175c7 | |||
| 0ebac6c98e | |||
| 15e363f34e | |||
| 2b6dc68ee5 | |||
| e39f4eb097 | |||
| 4ef1b69f83 | |||
| a77023165b | |||
| 62616b5e7b | |||
| 79b688c38e | |||
| 4995cac9b8 | |||
| d7c826fac6 | |||
| d668e0e5a7 | |||
| 63cb0b928f | |||
| 361e9dd1aa | |||
| 3f69dbf67e | |||
| 43b75502f7 | |||
| 4a565efff1 | |||
| 54955daff4 | |||
| 4047707fa8 | |||
| 5b1690bfbf | 
							
								
								
									
										58
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								README.md
									
									
									
									
									
								
							| @ -2,6 +2,62 @@ AC-Tube | ||||
| ======= | ||||
| Open Source CAPWAP WLC + WTP | ||||
|  | ||||
| Current status: early development. | ||||
| Current status: development. | ||||
|  | ||||
| See also http://7u83.cauwersin.com/?cat=28 | ||||
|  | ||||
| What you can do so far ... | ||||
|  | ||||
| Read INSTALL and compile actube. | ||||
|  | ||||
| Then ... | ||||
|  | ||||
| Create certificates: | ||||
|      | ||||
|      cd ssl | ||||
|      sh all.sh | ||||
|      cd .. | ||||
|  | ||||
| Edit src/actube/config.ckv and set your IP in | ||||
| capwap/control-ip-address/address.0 | ||||
|  | ||||
| Start actube with some debug options: | ||||
|      | ||||
|      cd src/ac | ||||
|      ./actube -d std -d mod -d elem\_detail -d elem\_dmp | ||||
|  | ||||
| If you have an AP with IOS 7.3x it should connect. Others | ||||
| might connect, too. | ||||
|  | ||||
| Make sure on the AP you heve made | ||||
| clear capwap private-config. | ||||
|  | ||||
| In another terminal window connect to the RPC interface: | ||||
|      | ||||
|      cd src/ac | ||||
|      ./act -s 127.0.0.1:5000 | ||||
|  | ||||
| Send some commands to bring up a WLAN: | ||||
|      | ||||
|      list                # list all connected APs | ||||
|      select <apname>     # set <apname> to the name of AP you want to select | ||||
|      status 		# show status of selected AP | ||||
|  | ||||
|      # the following sequence activates a WLAN called actube on AP | ||||
|  | ||||
|      load wlan1 | ||||
|      send | ||||
|      clear | ||||
|      load activate | ||||
|      send | ||||
|  | ||||
|      status		# This should display now oper status for  | ||||
| 			    # interface 0 enabled | ||||
|  | ||||
|  | ||||
| CWAPWAP data layer is still not finished, so you can't use the WLAN | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,35 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <CodeLite_Workspace Name="actube" Database=""> | ||||
|   <Project Name="ac" Path="ac.project" Active="No"/> | ||||
|   <Project Name="wtp" Path="wtp.project" Active="No"/> | ||||
|   <Project Name="mod_cipwap" Path="mod_cipwap.project" Active="No"/> | ||||
|   <Project Name="mod_capwap" Path="mod_capwap.project" Active="No"/> | ||||
|   <Project Name="mod_cisco" Path="mod_cisco.project" Active="Yes"/> | ||||
|   <Project Name="libcw" Path="libcw.project" Active="No"/> | ||||
|   <Project Name="mod_capwap80211" Path="mod_capwap80211.project" Active="No"/> | ||||
|   <Project Name="mod_fortinet" Path="mod_fortinet.project" Active="No"/> | ||||
|   <BuildMatrix> | ||||
|     <WorkspaceConfiguration Name="Debug" Selected="yes"> | ||||
|       <Environment/> | ||||
|       <Project Name="ac" ConfigName="Debug"/> | ||||
|       <Project Name="wtp" ConfigName="Debug"/> | ||||
|       <Project Name="mod_cipwap" ConfigName="Debug"/> | ||||
|       <Project Name="mod_capwap" ConfigName="Debug"/> | ||||
|       <Project Name="mod_cisco" ConfigName="Debug"/> | ||||
|       <Project Name="libcw" ConfigName="Debug"/> | ||||
|       <Project Name="mod_capwap80211" ConfigName="Debug"/> | ||||
|       <Project Name="mod_fortinet" ConfigName="Debug"/> | ||||
|     </WorkspaceConfiguration> | ||||
|     <WorkspaceConfiguration Name="Release" Selected="yes"> | ||||
|       <Environment/> | ||||
|       <Project Name="ac" ConfigName="Release"/> | ||||
|       <Project Name="wtp" ConfigName="Release"/> | ||||
|       <Project Name="mod_cipwap" ConfigName="Release"/> | ||||
|       <Project Name="mod_capwap" ConfigName="Release"/> | ||||
|       <Project Name="mod_cisco" ConfigName="Release"/> | ||||
|       <Project Name="libcw" ConfigName="Release"/> | ||||
|       <Project Name="mod_capwap80211" ConfigName="Release"/> | ||||
|       <Project Name="mod_fortinet" ConfigName="Release"/> | ||||
|     </WorkspaceConfiguration> | ||||
|   </BuildMatrix> | ||||
| </CodeLite_Workspace> | ||||
| @ -9,6 +9,7 @@ OBJS = \ | ||||
| 	discovery_cache.o\ | ||||
| 	rpc.o\ | ||||
| 	statemachine.o\ | ||||
| 	hapd.o | ||||
|  | ||||
| ACTOBJS = \ | ||||
| 	act.o  | ||||
| @ -26,13 +27,19 @@ LIBS+=-lnettle | ||||
| LIBS+=-lssl | ||||
| LIBS+=-lcrypto | ||||
| LIBS+=-ledit | ||||
| LIBS+=-lwifi | ||||
| #LIBS+=-l:libhapd.a | ||||
|  | ||||
| INCL_DIRS=-I../ -I/usr/local/include -I./ -I../../include | ||||
| INCL_DIRS=-I../ -I/usr/local/include -I./ -I../../include -I../../include/hostapd -I../../include/hostapd/utils | ||||
| #FLAGS=-DWITH_IPV6 -DWITH_OPENSSL -DSYS_ARCH="$(ARCH)" -DSYS_ARCH="XXX" | ||||
| FLAGS=-DWITH_IPV6 -DUSE_OPENSSL -DSYS_ARCH='"$(KERNEL)/$(ARCH)"' | ||||
|  | ||||
| all: act actube | ||||
|  | ||||
| act: act.c | ||||
| 	$(CC) act.c $(INCL_DIRS) $(LIBPATH) -DSYS_ARCH='"$(KERNEL)/$(ARCH)"' -o act -l:libcw.a -lasan -lcrypto -ledit | ||||
|  | ||||
| 	 | ||||
|  | ||||
| .c.o: | ||||
| 	@echo "  $(CC) "$< | ||||
| @ -43,8 +50,9 @@ all: $(PRG) $(ACTPRG) | ||||
| $(PRG): $(OBJS)  | ||||
| 	$(CC) $(OBJS) -o $(PRG) $(LIBPATH) $(LDFLAGS) $(LIBS)  | ||||
|  | ||||
| $(ACTPRG): $(ACTOBJS) | ||||
| 	$(CC) $(ACTOBJS) -o $(ACTPRG) $(LIBPATH) $(LDFLAGS) $(LIBS) -ledit  | ||||
| #$(ACTPRG): $(ACTOBJS) | ||||
| #	$(CC) $(ACTOBJS) -o $(ACTPRG) $(LIBPATH) $(LIBS) -ledit   | ||||
| 	#$(CC) $(ACTOBJS) $(ACTPRG) $(LIBPATH) $(LDFLAGS) $(LIBS) -ledit   | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -20,6 +20,7 @@ enum { | ||||
| int start_rpc(cw_Cfg_t *global_cfg); | ||||
| int test_shell(); | ||||
|  | ||||
| void hapd_run(); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
| @ -124,10 +124,21 @@ static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg) | ||||
| 			case '?': | ||||
| 				exit(EXIT_FAILURE); | ||||
| 			default: | ||||
| 			case 'h': | ||||
| 				printf("%s: -vcmh\n",argv[0]); | ||||
| 			case 'h':  | ||||
| 			{ | ||||
| 				FILE *out = stdout; | ||||
| 				fprintf(out, "Usage:"); | ||||
| 				fprintf(out, "%s [ options ] ",argv[0]); | ||||
| 				fprintf(out, "\nOptions are:\n"); | ||||
| 				fprintf(out, "  -c <file>:  specify a config file\n"); | ||||
| 				fprintf(out, "  -p <path>:  specify a path where to search for modules\n"); | ||||
| 				fprintf(out, "  -v:         print version information\n"); | ||||
| 				fprintf(out, "  -d <level>: set debug level, multiple -d's are possible\n");  | ||||
| 				fprintf(out, "    <level> can be one of these:\n"); | ||||
| 				cw_dbg_print_help(out,"    "); | ||||
| 				exit(EXIT_SUCCESS); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return 0; | ||||
| @ -200,6 +211,7 @@ return 0; | ||||
| */ | ||||
|  | ||||
| static cw_Cfg_t * global_cfg = NULL; | ||||
| void process_wtp_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len, int dta); | ||||
|  | ||||
|  | ||||
| int main (int argc, char *argv[]) | ||||
| @ -225,6 +237,12 @@ int main (int argc, char *argv[]) | ||||
| 		goto errX; | ||||
| 	}; | ||||
|  | ||||
| hapd_run(); // init | ||||
| //stop(); | ||||
| //const char *ttt = cw_cfg_get(global_cfg,"cisco/ssl-cipher",NULL); | ||||
| //printf("CFG: %s\n",ttt); | ||||
| //stop(); | ||||
|  | ||||
| 	cw_log_name = "AC-Tube"; | ||||
|  | ||||
| /* | ||||
| @ -440,7 +458,7 @@ int ac_run(cw_Cfg_t * cfg) | ||||
| 				                        (struct sockaddr *) &srcaddr, | ||||
| 				                        &srcaddrlen); | ||||
| 				                         | ||||
| 				process_cw_data_packet (i, (struct sockaddr *) &srcaddr, buffer, len); | ||||
| 				process_wtp_packet (i, (struct sockaddr *) &srcaddr, buffer, len,1); | ||||
| 				 | ||||
| 			} | ||||
| 			 | ||||
| @ -453,7 +471,7 @@ int ac_run(cw_Cfg_t * cfg) | ||||
| 				                        (struct sockaddr *) &srcaddr, | ||||
| 				                        &srcaddrlen); | ||||
| 				                         | ||||
| 				process_ctrl_packet (i, (struct sockaddr *) &srcaddr, buffer, len); | ||||
| 				process_wtp_packet (i, (struct sockaddr *) &srcaddr, buffer, len,0); | ||||
| 			} | ||||
| 			 | ||||
| 		} | ||||
| @ -467,14 +485,14 @@ int ac_run(cw_Cfg_t * cfg) | ||||
| void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len) | ||||
| { | ||||
| 	char sock_buf[SOCK_ADDR_BUFSIZE]; | ||||
| 	cw_dbg (DBG_X, "There is a data packet now"); | ||||
| //	cw_dbg (DBG_X, "There is a data packet now"); | ||||
| 	 | ||||
| 	dataman_list_lock(); | ||||
| 	cw_dbg (DBG_X, "Dataman list locked, now getting"); | ||||
| //	cw_dbg (DBG_X, "Dataman list locked, now getting"); | ||||
| 	struct dataman * dm = dataman_list_get (socklist[index].data_sockfd, addr); | ||||
| 	cw_dbg (DBG_X, "Dataman list locked, now gotted"); | ||||
| //	cw_dbg (DBG_X, "Dataman list locked, now gotted"); | ||||
| 	 | ||||
| 	cw_dbg (DBG_INFO, "Packet for dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd); | ||||
| //	cw_dbg (DBG_INFO, "Packet for dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd); | ||||
| 	 | ||||
| 	if (!dm) { | ||||
| 		cw_dbg (DBG_INFO, "No dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd); | ||||
| @ -486,15 +504,12 @@ void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer, | ||||
| 		} | ||||
| 		 | ||||
| 		dataman_list_add (dm); | ||||
| 		 | ||||
| 		dataman_start (dm); | ||||
| 		 | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	dataman_list_unlock(); | ||||
| 	 | ||||
| 	//dataman_add_packet (dm, buffer, len); | ||||
| 	dataman_add_packet (dm, buffer, len); | ||||
| 	 | ||||
| 	return; | ||||
| 	 | ||||
| @ -517,7 +532,7 @@ void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer, | ||||
| } | ||||
|  | ||||
|  | ||||
| void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len) | ||||
| void process_wtp_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len, int dta) | ||||
| { | ||||
| 	char sock_buf[SOCK_ADDR_BUFSIZE]; | ||||
| 	 | ||||
| @ -537,6 +552,10 @@ void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, | ||||
|  | ||||
|  | ||||
| 	if (!wtpman) { | ||||
| 		if (dta){ | ||||
| 			cw_dbg(DBG_PKT_ERR,"Data packet w/o wtpman received, ignoring"); | ||||
| 			return; | ||||
| 		} | ||||
| 	 | ||||
| 		wtpman = wtpman_create (index, addr, preamble & 0xf, global_cfg); | ||||
| 		 | ||||
| @ -558,9 +577,12 @@ void process_cw_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, | ||||
| 		wtpman_start (wtpman, preamble & 0xf); | ||||
| 	} | ||||
| 	 | ||||
| 	//printf("Got Packet with len: %d\n",len); | ||||
|  | ||||
| 	wtpman_addpacket (wtpman, buffer, len); | ||||
| 	if(!dta) | ||||
| 		wtpman_addpacket (wtpman, buffer, len); | ||||
| 	else{ | ||||
| //		cw_dbg(DBG_X,"Data packet received"); | ||||
| 		wtpman_datapacket (wtpman, buffer, len); | ||||
| 	} | ||||
| 	wtplist_unlock(); | ||||
| } | ||||
|  | ||||
| @ -631,7 +653,7 @@ void process_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, in | ||||
| { | ||||
| 	switch (socklist[index].ac_proto) { | ||||
| 		case AC_PROTO_CAPWAP: | ||||
| 			process_cw_ctrl_packet (index, addr, buffer, len); | ||||
| //			process_cw_ctrl_packet (index, addr, buffer, len); | ||||
| 			return; | ||||
| 			 | ||||
| 		/*case AC_PROTO_LWAPP: | ||||
|  | ||||
| @ -15,10 +15,18 @@ capwap/ssl-dhbits: 1024 | ||||
| capwap/ssl-keyfile:  "../../ssl/intermediate-ca/int-ca.key" | ||||
| capwap/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt" | ||||
|  | ||||
| cisco/ssl-keyfile:  "../../ssl/intermediate-ca/int-ca.key" | ||||
| cisco/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt" | ||||
| cisco/ssl-cipher: DEFAULT | ||||
| cisco/ssl-dhbits: 2048 | ||||
| #mod/cisco/ssl-keyfile:  "../../ssl/intermediate-ca/int-ca.key" | ||||
| #mod/cisco/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt" | ||||
| # | ||||
| mod/cisco/ssl-keyfile:  "../../ssl/certs/ac-cisco.key" | ||||
| mod/cisco/ssl-certfile: "../../ssl/certs/ac-cisco.pem" | ||||
|  | ||||
| #cisco/ssl-cipher: DEFAULT | ||||
| mod/cisco/ssl-cipher: RSA | ||||
| mod/cisco/ssl-dhbits: 2048 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #  | ||||
| @ -43,7 +51,15 @@ actube/mod.2: capwap80211 | ||||
| #actube/rpc/listen: unix:/tmp/actube | ||||
| actube/rpc/listen: tcp:127.0.0.1:5000 | ||||
| actube/rpc/enable: true | ||||
| actube/rpc/macros-dir: ./rpc-macros | ||||
|  | ||||
| # | ||||
| # This catches the initial config af a connecting WTP | ||||
| # From Discovery to CFG Update | ||||
| # The config is saved to a file named | ||||
| # wtp-<wtpname-or-ip>.cfg | ||||
| # | ||||
| actube/save-initial-wtp-config: true | ||||
|  | ||||
| capwap/ac-descriptor/dtls-policy:  1 | ||||
| capwap/ac-descriptor/hardware/vendor: 4232704 | ||||
| @ -59,17 +75,100 @@ capwap/ac-descriptor/station-limit: 1000 | ||||
| capwap/ac-descriptor/stations: 0 | ||||
|  | ||||
|  | ||||
| capwap/control-ip-address/address.0: 192.168.0.24 | ||||
| capwap/control-ip-address/address.0: 192.168.0.14 | ||||
|  | ||||
|  | ||||
| wlan.0/capwap80211/capability: 0 | ||||
| wlan.0/capwap80211/key-index: 0 | ||||
| wlan.0/capwap80211/key-status: 0 | ||||
| wlan.0/capwap80211/key: 1234 | ||||
| wlan.0/capwap80211/group-tcs: 123 | ||||
| wlan.0/capwap80211/qos: 0 | ||||
| wlan.0/capwap80211/auth-type: 1 | ||||
| wlan.0/capwap80211/mac-mode: 1 | ||||
| wlan.0/capwap80211/tunnel-mode: 1 | ||||
| wlan.0/capwap80211/suppress-ssid: false | ||||
| wlan.0/capwap80211/ssid: ssid | ||||
|  | ||||
|  | ||||
| # | ||||
| # CAPWAP Timers | ||||
| # | ||||
| capwap/timers/change-state-pending-timer: Word: 3 | ||||
| capwap/timers/data-check-timer: Word: 10 | ||||
| capwap/timers/echo-interval :Byte: 30 | ||||
| capwap/timers/max-discovery-interval :Byte: 10 | ||||
| capwap/timers/change-state-pending-timer: 3 | ||||
| capwap/timers/data-check-timer: 10 | ||||
| capwap/timers/echo-interval: 30 | ||||
| capwap/timers/max-discovery-interval: 10 | ||||
| capwap/decryption-error-report-period: 120 | ||||
| capwap/idle-timeout: 300 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/beacon-period: 100 | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/bssid: .x003a9902fac0 | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/cfg-period: 4 | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/beacon-period: 100 | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/bssid: .x003a9902fac0 | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/cfg-period: 4 | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/cfg-type: 1 | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/cfp-maximum-duration: 60 | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/country-str1: "DE " | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/country-str2: "DE " | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/occupancy-limit: 100 | ||||
| radio-cfg-a/capwap80211/wtp-radio-config/reg: 167772416 | ||||
|  | ||||
| radio-cfg-a/cisco/direct-sequence-control/cfg-type: 1 - global | ||||
| radio-cfg-a/cisco/direct-sequence-control/current-cca-mode: 0 | ||||
| radio-cfg-a/cisco/direct-sequence-control/current-channel: 1 | ||||
| radio-cfg-a/cisco/direct-sequence-control/energy-detect-threshold: -50 | ||||
|  | ||||
| #mode-802.11g support | ||||
| #radio-cfg-a/cisco/direct-sequence-control/unknown: 1      | ||||
|  | ||||
|  | ||||
| radio-cfg-a/cisco/mac-operation/fragmentation-threshold: 2346 | ||||
| radio-cfg-a/cisco/mac-operation/long-retry: 4 | ||||
| radio-cfg-a/cisco/mac-operation/reserved: 1 | ||||
| radio-cfg-a/cisco/mac-operation/rts-threshold: 2347 | ||||
| radio-cfg-a/cisco/mac-operation/rx-msdu-lifetime: 512 | ||||
| radio-cfg-a/cisco/mac-operation/short-retry: 7 | ||||
| radio-cfg-a/cisco/mac-operation/tx-msdu-lifetime: 512 | ||||
|  | ||||
|  | ||||
| radio-cfg-a/cisco/multi-domain-capability/first-channel: 1 | ||||
| radio-cfg-a/cisco/multi-domain-capability/max-tx-power-level: 65535 | ||||
| radio-cfg-a/cisco/multi-domain-capability/number-of-channels: 13 | ||||
| radio-cfg-a/cisco/multi-domain-capability/reserved: 1 | ||||
|  | ||||
| radio-cfg-a/capwap80211/rate-set: .x82848b960c1218243048606c | ||||
|  | ||||
| radio-cfg-a/cisco/antenna-payload/802-11n-rx-antennas: 3 | ||||
| radio-cfg-a/cisco/antenna-payload/802-11n-tx-antennas: 7 | ||||
| radio-cfg-a/cisco/antenna-payload/antenna-cnt: 2 | ||||
| radio-cfg-a/cisco/antenna-payload/antenna-mode: 3 | ||||
| radio-cfg-a/cisco/antenna-payload/antenna.0: 1 - Internal Antenna | ||||
| radio-cfg-a/cisco/antenna-payload/antenna.1: 1 - Internal Antenna | ||||
| radio-cfg-a/cisco/antenna-payload/diversity-selection: 255 | ||||
| radio-cfg-a/cisco/antenna-payload/unknown: 0 | ||||
|  | ||||
|  | ||||
|  | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/beacon-period: 100 | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/bssid: .x003a9902fac0 | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/cfg-period: 4 | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/beacon-period: 100 | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/bssid: .x003a9902fac0 | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/cfg-period: 4 | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/cfg-type: 1 | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/cfp-maximum-duration: 60 | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/country-str1: "DE " | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/country-str2: "DE " | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/occupancy-limit: 100 | ||||
| radio-cfg-b/capwap80211/wtp-radio-config/reg: 167772416 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										123
									
								
								src/ac/dataman.c
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								src/ac/dataman.c
									
									
									
									
									
								
							| @ -5,10 +5,12 @@ | ||||
| #include "cw/timer.h" | ||||
| #include "cw/cw.h" | ||||
| #include "cw/format.h" | ||||
| #include "cw/netconn.h" | ||||
| #include "cw/conn.h" | ||||
|  | ||||
| #include "cw/log.h" | ||||
| #include "cw/dbg.h" | ||||
| #include "cw/file.h" | ||||
| #include "cw/dot11.h" | ||||
|  | ||||
| #include "wtplist.h" | ||||
| #include "dataman.h" | ||||
| @ -19,8 +21,8 @@ pthread_mutex_t dataman_list_mutex; | ||||
|  | ||||
| static int cmp(const void *d1, const void *d2) | ||||
| { | ||||
| 	struct netconn *nc1 = ((struct dataman *) d1)->nc; | ||||
| 	struct netconn *nc2 = ((struct dataman *) d1)->nc; | ||||
| 	struct cw_Conn *nc1 = ((struct dataman *) d1)->nc; | ||||
| 	struct cw_Conn *nc2 = ((struct dataman *) d1)->nc; | ||||
|  | ||||
| 	int r = nc1->sock - nc2->sock; | ||||
| 	if (r != 0) | ||||
| @ -52,7 +54,7 @@ void dataman_destroy(struct dataman *dm) | ||||
| { | ||||
| 	if (!dm) | ||||
| 		return; | ||||
| 	netconn_destroy(dm->nc); | ||||
| 	conn_destroy(dm->nc); | ||||
| } | ||||
|  | ||||
| struct dataman *dataman_create(int sock, struct sockaddr *addr) | ||||
| @ -60,15 +62,15 @@ struct dataman *dataman_create(int sock, struct sockaddr *addr) | ||||
| 	struct dataman *dm = malloc(sizeof(struct dataman)); | ||||
| 	if (!dm) | ||||
| 		return NULL; | ||||
|  | ||||
| 	dm->nc = netconn_create(sock, addr, 100); | ||||
| 	memset(dm,0,sizeof(struct dataman)); | ||||
| 	dm->nc = cw_conn_create(sock, addr, 100); | ||||
| 	return dm; | ||||
| } | ||||
|  | ||||
|  | ||||
| struct dataman *dataman_list_get(int sock, struct sockaddr *addr) | ||||
| { | ||||
| 	struct netconn search_nc; | ||||
| 	struct cw_Conn search_nc; | ||||
| 	struct dataman search_dm; | ||||
|  | ||||
| 	search_nc.sock = sock; | ||||
| @ -78,7 +80,7 @@ struct dataman *dataman_list_get(int sock, struct sockaddr *addr) | ||||
|  | ||||
| 	struct dataman *dm = mavl_get(dataman_list, &search_dm); | ||||
|  | ||||
| 	cw_dbg(DBG_X,"Getting dataman %p",dm);  | ||||
| //	cw_dbg(DBG_X,"Getting dataman %p",dm);  | ||||
| 	return dm; | ||||
| } | ||||
|  | ||||
| @ -91,7 +93,7 @@ struct dataman *dataman_list_add(struct dataman *dm) | ||||
|  | ||||
|  | ||||
|  | ||||
| int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len) | ||||
| int dataman_process_keep_alive(struct cw_Conn *nc, uint8_t *rawmsg, int len) | ||||
| { | ||||
| 	struct dataman * dm = (struct dataman *)(nc->data); | ||||
|  | ||||
| @ -133,7 +135,7 @@ int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len) | ||||
| 				printf("len len %d\n",l); | ||||
| 				printf("Total len = %d\n",total_len); | ||||
|  | ||||
| 				netconn_send_capwap_msg(nc,buffer,total_len); | ||||
| 				cw_send_msg(nc,buffer,total_len); | ||||
| 				return len; | ||||
| 					 | ||||
|  | ||||
| @ -167,26 +169,107 @@ int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len) | ||||
| 	return -1;	 | ||||
| } | ||||
|  | ||||
| int dataman_process_message0(struct netconn *nc, uint8_t * rawmsg, int len, | ||||
| #include <libwifi.h> | ||||
|  | ||||
| int dataman_process_message0(struct cw_Conn *nc, uint8_t * rawmsg, int len, | ||||
| 			struct sockaddr *from) | ||||
| { | ||||
|  | ||||
| 	static int c=0; | ||||
| 	char fn[100]; | ||||
| 	sprintf(fn,"wificap-%03d",c++); | ||||
| ///	cw_save_file(fn,(char*)rawmsg,len); | ||||
| ///	cw_dbg(DBG_X,"saving %d bytes",len); | ||||
| 	int offs =  cw_get_hdr_msg_offset(rawmsg); | ||||
| 	int rc; | ||||
| 	uint8_t * dot11frame = rawmsg + offs; | ||||
| 	int dot11len = len-offs; | ||||
|  | ||||
| //	cw_dbg(DBG_X,"802.11 - %s",dot11_get_frame_name(dot11frame)); | ||||
| //	extern void ppacket(uint8_t * p, int len); | ||||
|  | ||||
| 	 | ||||
| //	ppacket (dot11frame,len-cw_get_hdr_msg_offset(rawmsg)); | ||||
|  | ||||
|  | ||||
| 	struct libwifi_frame frame = {0}; | ||||
| 	struct libwifi_frame resp={0}; | ||||
|  | ||||
| //	cw_dbg(DBG_X,"802.11 - %s",dot11_get_frame_name(dot11frame)); | ||||
| //	cw_dbg(DBG_X,"802.11 - T&S: %d %d",dot11_get_type(dot11frame),dot11_get_subtype(dot11frame)); | ||||
|  | ||||
| 	rc = libwifi_get_wifi_frame(&frame, (unsigned char*)(dot11frame+1), dot11len-1, 0); | ||||
|  | ||||
| //	cw_dbg(DBG_X,"Frame CTL:%d,%d",frame.frame_control.type, frame.frame_control.subtype); | ||||
|  | ||||
|  | ||||
|  | ||||
| //	cw_dbg(DBG_X,"CMP???CTL:%d,%d (%d,%d)",frame.frame_control.type, frame.frame_control.subtype, | ||||
| //			TYPE_MANAGEMENT,SUBTYPE_ASSOC_REQ); | ||||
| 	 | ||||
| //	char ffr[1024]; | ||||
| //	cw_format_dot11_hdr(ffr,dot11frame,dot11len);	 | ||||
| //	cw_dbg(DBG_X,ffr); | ||||
| // | ||||
| // | ||||
|  | ||||
| 	if (frame.frame_control.type == TYPE_MANAGEMENT && | ||||
| 		frame.frame_control.subtype == SUBTYPE_ASSOC_REQ){ | ||||
| //		cw_dbg(DBG_X,"ASSOC REQ RECEIVED"); | ||||
| /*		libwifi_create_assoc_resp(&resp, | ||||
| 				frame.frame_control.transmitter, | ||||
| 				frame.frame_control.receiver, | ||||
| 				frame.frame_control.transmitter, | ||||
| 				1 | ||||
| 				);*/ | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //		stop(); | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	 | ||||
| 	/* The very first data message MUST be a keep-alive message */ | ||||
| 	if (!cw_get_hdr_flag_k(rawmsg)){ | ||||
|  | ||||
| //		cw_dbg(DBG_X,"No K Flag founde"); | ||||
| 		errno = EAGAIN; | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| //	cw_dbg(DBG_X, "Goto Keep Alive Pack"); | ||||
| 	return dataman_process_keep_alive(nc,rawmsg,len); | ||||
| } | ||||
|  | ||||
| int dataman_process_message(struct netconn *nc, uint8_t * rawmsg, int len, | ||||
| int dataman_process_message(struct cw_Conn *nc, uint8_t * rawmsg, int len, | ||||
| 			struct sockaddr *from) | ||||
| { | ||||
| 	if (cw_get_hdr_flag_k(rawmsg)){ | ||||
| 		return dataman_process_keep_alive(nc,rawmsg,len); | ||||
| 	} | ||||
| 	static int c=0; | ||||
|  | ||||
| 	char fn[100]; | ||||
| 	sprintf(fn,"wificap-%03d",c++); | ||||
| 	cw_save_file(fn,(char*)rawmsg,len); | ||||
|  | ||||
| 	extern void ppacket(uint8_t * p, int len); | ||||
|  | ||||
| 	ppacket (rawmsg,len); | ||||
|  | ||||
| 	cw_dbg(DBG_X,"There was someting else than dataman"); | ||||
|  | ||||
| 	return 1; | ||||
|  | ||||
| } | ||||
| @ -195,12 +278,22 @@ void dataman_run(struct dataman *dm) | ||||
| { | ||||
| 	time_t timer = cw_timer_start(2); | ||||
|  | ||||
| 	dm->nc->process_packet=netconn_process_packet; | ||||
| 	dm->nc->process_packet=conn_process_packet; | ||||
| 	dm->nc->process_message=dataman_process_message0; | ||||
| 	dm->nc->data = dm; | ||||
|  | ||||
|  | ||||
| 	while (1){ | ||||
| 		time_t timer = cw_timer_start(2); | ||||
| 		while (!cw_timer_timeout(timer)){ | ||||
| 			cw_read_messages(dm->nc); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
|  | ||||
| 	while (!cw_timer_timeout(timer)){ | ||||
| 		netconn_read_messages(dm->nc); | ||||
| 		cw_read_messages(dm->nc); | ||||
| 	} | ||||
|  | ||||
| 	if (!dm->wtpman){ | ||||
| @ -215,7 +308,7 @@ void dataman_run(struct dataman *dm) | ||||
| 	while (1){ | ||||
| 		time_t timer = cw_timer_start(2); | ||||
| 		while (!cw_timer_timeout(timer)){ | ||||
| 			netconn_read_messages(dm->nc); | ||||
| 			cw_read_messages(dm->nc); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -3,12 +3,11 @@ | ||||
|  | ||||
| #include <pthread.h> | ||||
|  | ||||
| /*#include "cw/netconn.h"*/ | ||||
|  | ||||
| #include "wtpman.h" | ||||
|  | ||||
| struct dataman { | ||||
| 	struct netconn *nc; | ||||
| 	struct cw_Conn *nc; | ||||
| 	pthread_t thread; | ||||
| 	struct wtpman * wtpman; | ||||
|  | ||||
| @ -28,6 +27,6 @@ extern pthread_mutex_t dataman_list_mutex; | ||||
| #define dataman_list_lock() pthread_mutex_lock(&dataman_list_mutex) | ||||
| #define dataman_list_unlock() pthread_mutex_unlock(&dataman_list_mutex) | ||||
|  | ||||
| #define dataman_add_packet(dm,data,len) (netconn_q_add_packet(dm->nc,data,len)) | ||||
| #define dataman_add_packet(dm,data,len) (conn_q_add_packet(dm->nc,data,len)) | ||||
|  | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										487
									
								
								src/ac/db.c
									
									
									
									
									
								
							
							
						
						
									
										487
									
								
								src/ac/db.c
									
									
									
									
									
								
							| @ -1,487 +0,0 @@ | ||||
|  | ||||
| #include <sqlite3.h> | ||||
|  | ||||
|  | ||||
| #include "cw/log.h" | ||||
| #include "cw/dbg.h" | ||||
|  | ||||
| #include "cw/conn.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "conf.h" | ||||
|  | ||||
| static sqlite3 *handle; | ||||
|  | ||||
|  | ||||
| static const char * init_tables = "\ | ||||
| 	CREATE TABLE IF NOT EXISTS acs (acid TEXT PRIMARY KEY, acname TEXT, lastseen TIMESTAMP); \ | ||||
| 	CREATE TABLE IF NOT EXISTS radios (\ | ||||
| 		wtpid TEXT,\ | ||||
| 		rid TEXT,\ | ||||
| 		key TEXT,\ | ||||
| 		sub_key,\ | ||||
| 		val TEXT, \ | ||||
| 		upd INTEGER, \ | ||||
| 		PRIMARY KEY (wtpid,rid,key,sub_key)\ | ||||
| 	);\ | ||||
| 	CREATE TABLE IF NOT EXISTS acips (acid TEXT,ip TEXT); \ | ||||
| 	CREATE TABLE IF NOT EXISTS wtps (wtpid TEXT PRIMARY KEY, acid TEXT,lastseen TIMESTAMP); \ | ||||
| 	CREATE TABLE IF NOT EXISTS wtpprops (\ | ||||
| 		wtpid TEXT NOT NULL,\ | ||||
| 		id TEXT NOT NULL,\ | ||||
| 		sub_id TEXT NOT NULL,\ | ||||
| 		val TEXT,\ | ||||
| 		upd INTEGER,\ | ||||
| 		PRIMARY KEY(wtpid,id,sub_id)\ | ||||
| 	);\ | ||||
| 	CREATE TABLE IF NOT EXISTS wlans (wlanid INTEGER PRIMARY KEY);\ | ||||
| 	CREATE TABLE IF NOT EXISTS wlanprops (wlanid INTEGER, id TEXT NOT NULL, val TEXT, PRIMARY KEY(wlanid,id));\ | ||||
| 	"; | ||||
| 	 | ||||
|  | ||||
|  | ||||
|  | ||||
| int db_init() | ||||
| { | ||||
|  | ||||
| 	int rc; | ||||
| 	const char * filename="ac.sqlite3"; | ||||
| 	cw_dbg(DBG_INFO,"Initializing Sqlite3 DB: %s, SQLite3 Version %s",filename,SQLITE_VERSION); | ||||
|  | ||||
| 	rc = sqlite3_config(SQLITE_CONFIG_SERIALIZED); | ||||
| 	if (rc!=SQLITE_OK){ | ||||
| 		cw_log(LOG_ERR,"Error configuring SQLite3: %s",sqlite3_errmsg(handle));  | ||||
| 		return 0; | ||||
| 	}  | ||||
| 	 | ||||
| 	rc = sqlite3_initialize(); | ||||
| 	if (rc!=SQLITE_OK){ | ||||
| 		cw_log(LOG_ERR,"Error initializing SQLite3 DB : %s",sqlite3_errmsg(handle));  | ||||
| 		return 0; | ||||
| 	}  | ||||
| 	 | ||||
|  | ||||
| 	 | ||||
| 	rc = sqlite3_open(filename,&handle); | ||||
| 	if (rc != SQLITE_OK) | ||||
| 	{ | ||||
| 		cw_log(LOG_ERR,"Error opening SQLite3 DB %s: %s",filename,sqlite3_errmsg(handle));  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	const char * cmd = init_tables; | ||||
| 	rc = sqlite3_exec(handle,cmd,0,0,0); | ||||
| 	if (rc) | ||||
| 	{ | ||||
| 		const char *em = sqlite3_errmsg(handle); | ||||
| 		cw_log(LOG_ERR,"Error executing SQL \"%s\"\nSQL Error Message: %s",cmd, em); | ||||
| 		return 0; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| static sqlite3_stmt * ping_stmt; | ||||
| static sqlite3_stmt * put_wtp_prop_stmt; | ||||
|  | ||||
|  | ||||
| static sqlite3_stmt * get_tasks_stmt; | ||||
|  | ||||
| static sqlite3_stmt * stmt_get_radio_tasks; | ||||
|  | ||||
| static sqlite3_stmt * stmt_ping_wtp; | ||||
| static sqlite3_stmt * stmt_put_radio_prop; | ||||
|  | ||||
| int db_start() | ||||
| { | ||||
| 	cw_dbg(DBG_INFO,"Starting Sqlite3 DB"); | ||||
|  | ||||
| 	const char *sql=""; | ||||
|  | ||||
| 	sqlite3_stmt *stmt; | ||||
| 	int rc = sqlite3_prepare_v2(handle, "INSERT OR REPLACE INTO acs (acid,acname) VALUES (?,?);",-1,&stmt,0); | ||||
| 	if (rc) | ||||
| 		goto errX; | ||||
|  | ||||
| 	rc = sqlite3_bind_text(stmt,1,conf_acid,-1,SQLITE_STATIC); | ||||
|  | ||||
| 	rc = sqlite3_bind_text(stmt,2,conf_acname,-1,SQLITE_STATIC); | ||||
|  | ||||
| 	sqlite3_step(stmt); | ||||
|  | ||||
| 	rc = sqlite3_prepare_v2(handle, "UPDATE acs SET lastseen=datetime('now') WHERE acid=?;",-1,&ping_stmt,0); | ||||
| 	rc = sqlite3_bind_text(ping_stmt,1,conf_acid,-1,SQLITE_STATIC); | ||||
|  | ||||
|  | ||||
| 	/* Prepare statement to update a WTP property */ | ||||
| 	sql = "INSERT OR REPLACE INTO wtpprops\ | ||||
|                 (wtpid,id,sub_id,val,upd)\ | ||||
|                 VALUES (?,?,?,?,?)"; | ||||
|  | ||||
| 	rc = sqlite3_prepare_v2(handle, sql,-1, &put_wtp_prop_stmt,0); | ||||
| 	if (rc)  | ||||
| 		goto errX; | ||||
|  | ||||
|  | ||||
| 	sql = "INSERT OR REPLACE INTO radios\ | ||||
| 	       (wtpid,rid,key,sub_key,val,upd)\ | ||||
| 	       VALUES (?,?,?,?,?,0)"; | ||||
|  | ||||
| 	rc = sqlite3_prepare_v2(handle, sql,-1, &stmt_put_radio_prop,0); | ||||
| 	if (rc)  | ||||
| 		goto errX; | ||||
|  | ||||
|  | ||||
| 	/* Prepare WTP ping statement */ | ||||
| 	sql = "INSERT OR REPLACE INTO wtps  (wtpid,acid,lastseen) VALUES(?,?,datetime('now'))"; | ||||
| 	rc = sqlite3_prepare_v2(handle, sql,-1, &stmt_ping_wtp,0); | ||||
| 	if (rc)  | ||||
| 		goto errX; | ||||
|  | ||||
|  | ||||
| 	 | ||||
| 	sql = "SELECT wtpid,id,sub_id,val FROM wtpprops WHERE upd>0 AND wtpid=?"; | ||||
| 	rc = sqlite3_prepare_v2(handle, sql,-1, &get_tasks_stmt,0); | ||||
| 	if (rc)  | ||||
| 		goto errX; | ||||
|  | ||||
|   | ||||
| 	sql = "SELECT wtpid,rid,key,sub_key,val FROM radios WHERE upd>0 AND wtpid=?"; | ||||
| 	rc = sqlite3_prepare_v2(handle, sql,-1, &stmt_get_radio_tasks,0); | ||||
| 	if (rc)  | ||||
| 		goto errX; | ||||
|  | ||||
|  | ||||
|  | ||||
| 	return 1; | ||||
|  | ||||
| errX: | ||||
| 	cw_log(LOG_ERR,"Fatal: Can't start Sqlite3 DB, Error while executing '%s' - %d - %s",sql,rc,sqlite3_errmsg(handle)); | ||||
| 	return 0; | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| void db_put_radio_prop(const char *wtp_id,const char *rid, const char * key,const char *sub_key,const char * val) | ||||
| { | ||||
| 	int rc=0; | ||||
|  | ||||
| /*//	DBGX("Putting %s/%s:%s",id,sub_id,val); | ||||
| //	       (wtpid,rid,key,sub_key,val,upd) | ||||
| */ | ||||
| 	sqlite3_reset(stmt_put_radio_prop); | ||||
| 	sqlite3_clear_bindings(stmt_put_radio_prop); | ||||
|  | ||||
| 	if(sqlite3_bind_text(stmt_put_radio_prop,1,wtp_id,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
| 	 | ||||
| 	if(sqlite3_bind_text(stmt_put_radio_prop,2,rid,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
|  | ||||
|  | ||||
| 	if (sqlite3_bind_text(stmt_put_radio_prop,3,key,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
|  | ||||
| /*	if (!sub_key)  | ||||
| 		sub_key=CW_ITEM_NONE; | ||||
| */ | ||||
| 	if (sqlite3_bind_text(stmt_put_radio_prop,4,sub_key,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
| 	if (sqlite3_bind_text(stmt_put_radio_prop,5,val,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
| 	 | ||||
| /* | ||||
| //	if (sqlite3_bind_int(put_wtp_prop_stmt,5,0)) | ||||
| //		goto errX; | ||||
|  | ||||
| //	cw_dbg(DBG_X,"Her I am already, next is step"); | ||||
| */ | ||||
| 	rc = sqlite3_step(stmt_put_radio_prop); | ||||
| 	if (rc != SQLITE_DONE) | ||||
| 		goto errX; | ||||
|  | ||||
| /* | ||||
| //	cw_dbg(DBG_X,"SQL schould be fine"); | ||||
| */ | ||||
| 	return; | ||||
| errX: | ||||
| /*//	cw_dbg (DBG_X, "Iam on err %d\n",rc);*/ | ||||
|  | ||||
|  | ||||
| 	if (rc) { | ||||
| 		cw_log(LOG_ERR,"Can't update database with WTP props: %d - %s", | ||||
| 			rc,sqlite3_errmsg(handle)); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| void db_ping() | ||||
| { | ||||
| 	int rc = sqlite3_step(ping_stmt); | ||||
| 	if (rc!=SQLITE_DONE){ | ||||
| 		cw_log(LOG_ERR,"Error: Can't ping database, error code %d - %s",rc,sqlite3_errmsg(handle)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| void db_ping_wtp(const char *wtpid,const char *acid) | ||||
| { | ||||
| 	int rc=0; | ||||
| 	sqlite3_reset(stmt_ping_wtp); | ||||
| 	sqlite3_clear_bindings(stmt_ping_wtp); | ||||
| 	if(sqlite3_bind_text(stmt_ping_wtp,1,wtpid,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
| 	 | ||||
| 	if(sqlite3_bind_text(stmt_ping_wtp,2,acid,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
| 	rc = sqlite3_step(stmt_ping_wtp); | ||||
| errX: | ||||
| 	if (rc!=SQLITE_DONE) { | ||||
| 		cw_log(LOG_ERR,"Can't ping database for WTP: %d - %s", | ||||
| 			rc,sqlite3_errmsg(handle)); | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| void db_put_wtp_prop(const char *wtp_id,const char * id,const char *sub_id,const char * val) | ||||
| { | ||||
| 	int rc=0; | ||||
|  | ||||
| /*//	DBGX("Putting %s/%s:%s",id,sub_id,val); | ||||
| */ | ||||
|  | ||||
| 	sqlite3_reset(put_wtp_prop_stmt); | ||||
| 	sqlite3_clear_bindings(put_wtp_prop_stmt); | ||||
|  | ||||
| 	if(sqlite3_bind_text(put_wtp_prop_stmt,1,wtp_id,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
| 	 | ||||
| 	if(sqlite3_bind_text(put_wtp_prop_stmt,2,id,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
| /*	if (!sub_id)  | ||||
| 		sub_id=CW_ITEM_NONE; | ||||
| */ | ||||
|  | ||||
| 	if (sqlite3_bind_text(put_wtp_prop_stmt,3,sub_id,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
| 	if (sqlite3_bind_text(put_wtp_prop_stmt,4,val,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
| 	if (sqlite3_bind_int(put_wtp_prop_stmt,5,0)) | ||||
| 		goto errX; | ||||
|  | ||||
| /*//	cw_dbg(DBG_X,"Her I am already, next is step"); | ||||
| */ | ||||
| 	rc = sqlite3_step(put_wtp_prop_stmt); | ||||
| 	if (rc != SQLITE_DONE) | ||||
| 		goto errX; | ||||
|  | ||||
| /* | ||||
| //	cw_dbg(DBG_X,"SQL schould be fine"); | ||||
| */ | ||||
| 	return; | ||||
| errX: | ||||
| /*//	cw_dbg (DBG_X, "Iam on err %d\n",rc);*/ | ||||
|  | ||||
|  | ||||
| 	if (rc) { | ||||
| 		cw_log(LOG_ERR,"Can't update database with WTP props: %d - %s", | ||||
| 			rc,sqlite3_errmsg(handle)); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| /*// TODO XXXX*/ | ||||
| mavl_t db_get_update_tasks(struct conn * conn,const char * wtpid) | ||||
| { | ||||
| /* | ||||
| 	sqlite3_reset(get_tasks_stmt); | ||||
| 	sqlite3_clear_bindings(get_tasks_stmt); | ||||
|  | ||||
| 	mavl_conststr_t r = mavl_create_conststr(); | ||||
| 	if (!r) | ||||
| 		return NULL; | ||||
|  | ||||
|  | ||||
| 	int rc=0; | ||||
|  | ||||
|  | ||||
| 	if(sqlite3_bind_text(get_tasks_stmt,1,wtpid,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
| 	while (SQLITE_ROW == sqlite3_step(get_tasks_stmt)) { | ||||
|  | ||||
| 		int ii; | ||||
| 		//DBGX("-----------------------------------------------------",""); | ||||
| 		for (ii=0; ii<5; ii++){ | ||||
|  | ||||
| 			//DBGX("CVALL: %s",(const char*)sqlite3_column_text(get_tasks_stmt,ii)); | ||||
|  | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		const char *id =  (const char*)sqlite3_column_text(get_tasks_stmt,1); | ||||
| 		if (!id) { | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		const char *sub_id =  (const char*)sqlite3_column_text(get_tasks_stmt,2); | ||||
|  | ||||
| 		const char *val =  (const char*)sqlite3_column_text(get_tasks_stmt,3); | ||||
|  | ||||
| 		//DBGX("ID: (%s), SubID (%s), Val (%s)",id,sub_id,val); | ||||
| 	 | ||||
| 		const struct cw_itemdef * cwi = cw_itemdef_get(conn->actions->items,id,sub_id); | ||||
| 		if (!cwi) { | ||||
| 			//DBGX("Not item definition found for: %s/%s",id,sub_id); | ||||
| 			continue;	 | ||||
| 		} | ||||
|  | ||||
| 		//uint8_t data[2048]; | ||||
|  | ||||
| 		if (!cwi->type->from_str) { | ||||
| 			cw_log(LOG_ERR,"Can't convert from string %s/%s - No method defined.",id,sub_id); | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		mbag_item_t * i = cwi->type->from_str(val); | ||||
| 		i->id=cwi->id; | ||||
|  | ||||
| 		mbag_set(conn->outgoing,i); | ||||
| 	 | ||||
| 		mavl_add(r,(void*)cwi->id); | ||||
| 	} | ||||
|  | ||||
| 	if (r->count) | ||||
| 		return r; | ||||
| 	 | ||||
| 	mavl_destroy(r); | ||||
| 	return NULL; | ||||
|  | ||||
|  | ||||
| errX: | ||||
| 	if (rc) { | ||||
| 		cw_log(LOG_ERR,"Can't get tasks: %d - %s", | ||||
| 			rc,sqlite3_errmsg(handle)); | ||||
| 	} | ||||
|  | ||||
| 	if (r) | ||||
| 		mavl_destroy(r); | ||||
| 		 | ||||
|  | ||||
| 	return NULL; | ||||
| */ | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| mavl_t db_get_radio_tasks(struct conn * conn,const char * wtpid) | ||||
| { | ||||
| /* | ||||
| //cw_dbg(DBG_X,"Get Radio Tasks for  %s",wtpid); | ||||
|  | ||||
| 	sqlite3_reset(stmt_get_radio_tasks); | ||||
| 	sqlite3_clear_bindings(stmt_get_radio_tasks); | ||||
|  | ||||
| 	mavl_conststr_t r = mavl_create_conststr(); | ||||
| 	if (!r) | ||||
| 		return NULL; | ||||
|  | ||||
|  | ||||
| 	int rc=0; | ||||
|  | ||||
|  | ||||
| 	if(sqlite3_bind_text(stmt_get_radio_tasks,1,wtpid,-1,SQLITE_STATIC)) | ||||
| 		goto errX; | ||||
|  | ||||
| 	while (SQLITE_ROW == sqlite3_step(stmt_get_radio_tasks)) { | ||||
|  | ||||
| 		int ii; | ||||
| 		//DBGX("-----------------------------------------------------",""); | ||||
| 		for (ii=0; ii<6; ii++){ | ||||
|  | ||||
| 			DBGX("CVALL: %s",(const char*)sqlite3_column_text(stmt_get_radio_tasks,ii)); | ||||
|  | ||||
|  | ||||
| 		} | ||||
| 		const char *strrid=  (const char*)sqlite3_column_text(stmt_get_radio_tasks,1); | ||||
|  | ||||
| 		const char *id =  (const char*)sqlite3_column_text(stmt_get_radio_tasks,2); | ||||
| 		if (!id) { | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		const char *sub_id =  (const char*)sqlite3_column_text(stmt_get_radio_tasks,3); | ||||
|  | ||||
| 		const char *val =  (const char*)sqlite3_column_text(stmt_get_radio_tasks,4); | ||||
|  | ||||
| 		//DBGX("ID: (%s), SubID (%s), Val (%s)",id,sub_id,val); | ||||
| 	 | ||||
| 		const struct cw_itemdef * cwi = cw_itemdef_get(conn->actions->radioitems,id,sub_id); | ||||
| 		if (!cwi) { | ||||
| 			DBGX("No item definition found for: %s/%s",id,sub_id); | ||||
| 			continue;	 | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		if (!cwi->type->from_str) { | ||||
| 			cw_log(LOG_ERR,"Can't convert from string %s/%s - No method defined.",id,sub_id); | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		mbag_item_t * i = cwi->type->from_str(val); | ||||
| 		i->id=cwi->id; | ||||
|  | ||||
| 		int rid = atoi(strrid);			 | ||||
| 		cw_dbg(DBG_X,"RID: %d",rid); | ||||
|  | ||||
|  | ||||
| 		mbag_t radio = mbag_i_get_mbag_c(conn->radios_upd,rid,mbag_create); | ||||
| 		mbag_set(radio,i); | ||||
|  | ||||
|  | ||||
| 		//mbag_set(conn->outgoing,i); | ||||
| 	 | ||||
| 		mavl_add(r,(void*)cwi->id); | ||||
| 	} | ||||
|  | ||||
| 	if (r->count) | ||||
| 		return r; | ||||
| 	 | ||||
| 	mavl_destroy(r); | ||||
| 	return NULL; | ||||
|  | ||||
|  | ||||
| errX: | ||||
| 	if (rc) { | ||||
| 		cw_log(LOG_ERR,"Can't get tasks: %d - %s", | ||||
| 			rc,sqlite3_errmsg(handle)); | ||||
| 	} | ||||
|  | ||||
| 	if (r) | ||||
| 		mavl_destroy(r); | ||||
| 		 | ||||
|  | ||||
| 	return NULL; | ||||
| */ | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										21
									
								
								src/ac/db.h
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/ac/db.h
									
									
									
									
									
								
							| @ -1,21 +0,0 @@ | ||||
| #ifndef CW_MAVL_H | ||||
| #define CW_MAVL_H | ||||
|  | ||||
| #include "mavl.h" | ||||
|  | ||||
| extern void db_ping(); | ||||
| extern void db_ping_wtp(const char *wtpid,const char *acid); | ||||
|  | ||||
| extern int db_init(); | ||||
| int db_start(); | ||||
| int db_get_tasks(struct conn * conn,const char * wtpid); | ||||
| void db_put_wtp_prop(const char *wtp_id,const char * id,const char *sub_id,const char * val); | ||||
| mavl_t db_get_update_tasks(struct conn * conn,const char * wtpid); | ||||
|  | ||||
| void db_put_radio_prop(const char *wtp_id,const char *rid, const char * key,const char *sub_key,const char * val); | ||||
| extern mavl_t db_get_radio_tasks(struct conn * conn,const char * wtpid); | ||||
|  | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
| @ -1,29 +0,0 @@ | ||||
|  | ||||
|  | ||||
| #include "module.h" | ||||
|  | ||||
|  | ||||
| static int init() | ||||
| { | ||||
| //	regn = cw_register_actions_cipwap_ac(&capwap_actions); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static struct ac_module module = { | ||||
| 	.name="Cipwap", | ||||
| 	.init= init, | ||||
| 	.detect_by_discovery = 0 | ||||
| 	 | ||||
|  | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| struct ac_module * mod_cipwap() | ||||
| { | ||||
|  | ||||
| 	return &module; | ||||
| } | ||||
| @ -1,13 +0,0 @@ | ||||
| #ifndef __MODULE_H | ||||
| #define __MODULE_H | ||||
|  | ||||
| struct ac_module | ||||
| { | ||||
| 	const char *name; | ||||
| 	int (*init)(); | ||||
| 	int (*detect_by_raw)(const char *msg, int len); | ||||
| 	int (*detect_by_discovery)(const char*); | ||||
| }; | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										5
									
								
								src/ac/rpc-macros/activate.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/ac/rpc-macros/activate.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| radio.255/capwap/operational-state/state: enabled | ||||
| radio.255/capwap/admin-state: 1 | ||||
| radio.0/capwap/operational-state/state: enabled | ||||
| radio.0/capwap/admin-state: 1 | ||||
|  | ||||
							
								
								
									
										5
									
								
								src/ac/rpc-macros/admin-on.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/ac/rpc-macros/admin-on.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| # | ||||
| # Managed by acTube | ||||
| # | ||||
|  | ||||
| radio.0/capwap/admin-state: 1 | ||||
							
								
								
									
										60
									
								
								src/ac/rpc-macros/all.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/ac/rpc-macros/all.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | ||||
|  | ||||
| radio.0/cisco/air-space-capability: 0 | ||||
| radio.0/cisco/antenna-payload/802-11n-rx-antennas: 3 | ||||
| radio.0/cisco/antenna-payload/802-11n-tx-antennas: 7 | ||||
| radio.0/cisco/antenna-payload/antenna-cnt: 2 | ||||
| radio.0/cisco/antenna-payload/antenna-mode: 3 | ||||
| radio.0/cisco/antenna-payload/antenna.0: 1 - Internal Antenna | ||||
| radio.0/cisco/antenna-payload/antenna.1: 1 - Internal Antenna | ||||
| radio.0/cisco/antenna-payload/diversity-selection: 255 | ||||
| radio.0/cisco/antenna-payload/unknown: 0 | ||||
|  | ||||
| radio.0/cisco/channel-power: .x08080d0108221c16100a04fefe0208221c16100a04fefe0308221c16100a04fefe0408221c16100a04fefe0508221c16100a04fefe0608221c16100a04fefe0708221c16100a04fefe0808221c16100a04fefe0908221c16100a04fefe0a08221c16100a04fefe0b08221c16100a04fefe0c08221c16100a04fefe0d08221c16100a04fefe | ||||
|  | ||||
| radio.0/capwap80211/rate-set: .x82848b960c1218243048606c | ||||
| radio.0/capwap80211/tx-power/@cisco/cfg-type: 1 - global | ||||
| radio.0/capwap80211/tx-power/current-tx-power: 1 | ||||
| radio.0/capwap80211/wtp-radio-config/beacon-period: 100 | ||||
| radio.0/capwap80211/wtp-radio-config/bssid: .x04fe7f499b90 | ||||
| radio.0/capwap80211/wtp-radio-config/cfg-period: 4 | ||||
| radio.0/capwap80211/wtp-radio-config/cfg-type: 1 | ||||
| radio.0/capwap80211/wtp-radio-config/cfp-maximum-duration: 60 | ||||
| radio.0/capwap80211/wtp-radio-config/country-str1: "DE " | ||||
| radio.0/capwap80211/wtp-radio-config/country-str2: "DE " | ||||
| radio.0/capwap80211/wtp-radio-config/occupancy-limit: 100 | ||||
| radio.0/capwap80211/wtp-radio-config/reg: 167772416 | ||||
| radio.0/capwap80211/wtp-radio-information: 1 | ||||
|  | ||||
|  | ||||
| radio.0/cisco/mac-operation/long-retry: 4 | ||||
| radio.0/cisco/mac-operation/reserved: 1 | ||||
| radio.0/cisco/mac-operation/rts-threshold: 2347 | ||||
| radio.0/cisco/mac-operation/rx-msdu-lifetime: 512 | ||||
| radio.0/cisco/mac-operation/short-retry: 7 | ||||
| radio.0/cisco/mac-operation/tx-msdu-lifetime: 512 | ||||
| radio.0/cisco/multi-domain-capability/first-channel: 1 | ||||
| radio.0/cisco/multi-domain-capability/max-tx-power-level: 65535 | ||||
| radio.0/cisco/multi-domain-capability/number-of-channels: 13 | ||||
| radio.0/cisco/multi-domain-capability/reserved: 1 | ||||
|  | ||||
| radio.0/cisco/phy-ht-cap/asel-cap: 0 | ||||
| radio.0/cisco/phy-ht-cap/extended-ht-cap-info: .x0000 | ||||
| radio.0/cisco/phy-ht-cap/ht-cap-info: 6 | ||||
| radio.0/cisco/phy-ht-cap/mcsrates-1: .x00000000 | ||||
| radio.0/cisco/phy-ht-cap/mcsrates-2: .x00000000 | ||||
| radio.0/cisco/phy-ht-cap/mcsrates-3: .x00000000 | ||||
| radio.0/cisco/phy-ht-cap/mcsrates-4: .x0000ffff | ||||
| radio.0/cisco/phy-ht-cap/tx-bf-cap: .x00000000 | ||||
| radio.0/cisco/phy-ht-control/cfg-type: 1 - global | ||||
| radio.0/cisco/phy-ht-control/channel-width: 20 | ||||
| radio.0/cisco/phy-ht-control/cur-freq-is-dfs-channel: 0 | ||||
| radio.0/cisco/phy-ht-control/current-freq: 1 | ||||
| radio.0/cisco/phy-ht-control/enable-ht: 3 | ||||
| radio.0/cisco/phy-ht-control/ext-channel: 0 | ||||
| radio.0/cisco/phy-ht-control/flash-commit: 0 | ||||
| radio.0/cisco/phy-ht-control/frequency-bands-support: 206 | ||||
| radio.0/cisco/phy-ht-control/rest: .x00ffffff | ||||
| radio.0/cisco/phy-ht-control/ti-threshold: 0 | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										10
									
								
								src/ac/rpc-macros/antenna.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/ac/rpc-macros/antenna.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| radio.0/cisco/air-space-capability: 0 | ||||
| radio.0/cisco/antenna-payload/802-11n-rx-antennas: 3 | ||||
| radio.0/cisco/antenna-payload/802-11n-tx-antennas: 7 | ||||
| radio.0/cisco/antenna-payload/antenna-cnt: 2 | ||||
| radio.0/cisco/antenna-payload/antenna-mode: 3 | ||||
| radio.0/cisco/antenna-payload/antenna.0: 1 - Internal Antenna | ||||
| radio.0/cisco/antenna-payload/antenna.1: 1 - Internal Antenna | ||||
| radio.0/cisco/antenna-payload/diversity-selection: 255 | ||||
| radio.0/cisco/antenna-payload/unknown: 0 | ||||
|  | ||||
							
								
								
									
										5
									
								
								src/ac/rpc-macros/led-off.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/ac/rpc-macros/led-off.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| # | ||||
| # Managed by acTube | ||||
| # | ||||
|  | ||||
| cisco/ap-led-state-config/led-state: 0 | ||||
							
								
								
									
										5
									
								
								src/ac/rpc-macros/led-on.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/ac/rpc-macros/led-on.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| # | ||||
| # Managed by acTube | ||||
| # | ||||
|  | ||||
| cisco/ap-led-state-config/led-state: 1 | ||||
							
								
								
									
										8
									
								
								src/ac/rpc-macros/macopts.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/ac/rpc-macros/macopts.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| radio.0/cisco/mac-operation/fragmentation-threshold: 2346 | ||||
| radio.0/cisco/mac-operation/long-retry: 4 | ||||
| radio.0/cisco/mac-operation/reserved: 1 | ||||
| radio.0/cisco/mac-operation/rts-threshold: 2347 | ||||
| radio.0/cisco/mac-operation/rx-msdu-lifetime: 512 | ||||
| radio.0/cisco/mac-operation/short-retry: 7 | ||||
| radio.0/cisco/mac-operation/tx-msdu-lifetime: 512 | ||||
|  | ||||
							
								
								
									
										5
									
								
								src/ac/rpc-macros/oper-off.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/ac/rpc-macros/oper-off.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| # | ||||
| # Managed by acTube | ||||
| # | ||||
|  | ||||
| radio.0/capwap/operational-state/state: disabled | ||||
							
								
								
									
										5
									
								
								src/ac/rpc-macros/oper-on.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/ac/rpc-macros/oper-on.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| # | ||||
| # Managed by acTube | ||||
| # | ||||
|  | ||||
| radio.0/capwap/operational-state/state: enabled | ||||
							
								
								
									
										13
									
								
								src/ac/rpc-macros/radio.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/ac/rpc-macros/radio.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| radio.0/capwap80211/tx-power/@cisco/cfg-type: 1 - global | ||||
| radio.0/capwap80211/tx-power/current-tx-power: 1 | ||||
| radio.0/capwap80211/wtp-radio-config/beacon-period: 100 | ||||
| radio.0/capwap80211/wtp-radio-config/bssid: .x04fe7f499b90 | ||||
| radio.0/capwap80211/wtp-radio-config/cfg-period: 4 | ||||
| radio.0/capwap80211/wtp-radio-config/cfg-type: 1 | ||||
| radio.0/capwap80211/wtp-radio-config/cfp-maximum-duration: 60 | ||||
| radio.0/capwap80211/wtp-radio-config/country-str1: "DE " | ||||
| radio.0/capwap80211/wtp-radio-config/country-str2: "DE " | ||||
| radio.0/capwap80211/wtp-radio-config/occupancy-limit: 100 | ||||
| radio.0/capwap80211/wtp-radio-config/reg: 167772416 | ||||
| radio.0/capwap80211/wtp-radio-information: 1 | ||||
|  | ||||
							
								
								
									
										89
									
								
								src/ac/rpc-macros/sr.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/ac/rpc-macros/sr.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | ||||
| capwap/timers/echo-interval: 30 | ||||
| capwap/timers/max-discovery-interval: 10 | ||||
|  | ||||
| radio.255/capwap/admin-state: 1 - enabled | ||||
| radio.0/capwap/admin-state: 1 - enabled | ||||
| radio.1/capwap/admin-state: 1 - enabled | ||||
|  | ||||
| radio.0/capwap/decryption-error-report-period: 120 | ||||
| radio.1/capwap/decryption-error-report-period: 120 | ||||
|  | ||||
| capwap/idle-timeout: 300 | ||||
|  | ||||
| capwap/wtp-fallback: 1 | ||||
|  | ||||
| cisco/spam-domain-secret: .xe1ffd18a8f15b3b59c0a47a7f17a96e7cb36174f00 | ||||
|  | ||||
| radio.0/capwap80211/wtp-radio-config/beacon-period: 100 | ||||
| radio.0/capwap80211/wtp-radio-config/bssid: .x003a9902fac0 | ||||
| radio.0/capwap80211/wtp-radio-config/cfg-period: 4 | ||||
| radio.0/capwap80211/wtp-radio-config/cfg-type: 1 | ||||
| radio.0/capwap80211/wtp-radio-config/cfp-maximum-duration: 60 | ||||
| radio.0/capwap80211/wtp-radio-config/country-str1: "DE " | ||||
| radio.0/capwap80211/wtp-radio-config/country-str2: "DE " | ||||
| radio.0/capwap80211/wtp-radio-config/occupancy-limit: 100 | ||||
| radio.0/capwap80211/wtp-radio-config/reg: 167772416 | ||||
| radio.0/capwap80211/wtp-radio-information: 1 | ||||
|  | ||||
| radio.0/capwap80211/rate-set: .x82848b960c1218243048606c | ||||
|  | ||||
| radio.0/cisco/multi-domain-capability/first-channel: 1 | ||||
| radio.0/cisco/multi-domain-capability/max-tx-power-level: 65535 | ||||
| radio.0/cisco/multi-domain-capability/number-of-channels: 13 | ||||
| radio.0/cisco/multi-domain-capability/reserved: 1 | ||||
|  | ||||
| radio.0/cisco/mac-operation/fragmentation-threshold: 2346 | ||||
| radio.0/cisco/mac-operation/long-retry: 4 | ||||
| radio.0/cisco/mac-operation/reserved: 1 | ||||
| radio.0/cisco/mac-operation/rts-threshold: 2347 | ||||
| radio.0/cisco/mac-operation/rx-msdu-lifetime: 512 | ||||
| radio.0/cisco/mac-operation/short-retry: 7 | ||||
| radio.0/cisco/mac-operation/tx-msdu-lifetime: 512 | ||||
|  | ||||
| radio.1/capwap80211/tx-power/@cisco/cfg-type: 1 - global | ||||
| radio.1/capwap80211/tx-power/current-tx-power: 1 | ||||
|  | ||||
| radio.0/cisco/direct-sequence-control/cfg-type: 1 - global | ||||
| radio.0/cisco/direct-sequence-control/current-cca-mode: 0 | ||||
| radio.0/cisco/direct-sequence-control/current-channel: 1 | ||||
| radio.0/cisco/direct-sequence-control/energy-detect-threshold: -50 | ||||
| radio.0/cisco/direct-sequence-control/unknown: 1 | ||||
|  | ||||
| radio.0/cisco/antenna-payload/802-11n-rx-antennas: 3 | ||||
| radio.0/cisco/antenna-payload/802-11n-tx-antennas: 7 | ||||
| radio.0/cisco/antenna-payload/antenna-cnt: 2 | ||||
| radio.0/cisco/antenna-payload/antenna-mode: 3 | ||||
| radio.0/cisco/antenna-payload/antenna.0: 1 - Internal Antenna | ||||
| radio.0/cisco/antenna-payload/antenna.1: 1 - Internal Antenna | ||||
| radio.0/cisco/antenna-payload/diversity-selection: 255 | ||||
| radio.0/cisco/antenna-payload/unknown: 0 | ||||
|  | ||||
| radio.0/cisco/air-space-capability: 0 | ||||
|  | ||||
| radio.0/capwap/operational-state/cause: Normal | ||||
| radio.0/capwap/operational-state/state: enabled | ||||
|  | ||||
| radio.0/cisco/80211h/count: 0 | ||||
| radio.0/cisco/80211h/enable: 0 | ||||
| radio.0/cisco/80211h/mode: 0 | ||||
| radio.0/cisco/80211h/power: 0 | ||||
|  | ||||
| radio.0/cisco/elem153: .x00 | ||||
| radio.0/cisco/elem156: .x020100 | ||||
| radio.0/cisco/lwelem48: .x01055a0101a6c405b06432b03232 | ||||
| radio.1/cisco/lwelem33: .x00 | ||||
| radio.0/cisco/elem146: .x690f | ||||
|  | ||||
| radio.255/capwap/operational-state/cause: Normal | ||||
| radio.255/capwap/operational-state/state: enabled | ||||
|  | ||||
| cisco/bcast-ssid-mode: 1 | ||||
| capwap/timers/max-discovery-interval: 10 | ||||
| capwap/timers/echo-interval: 30 | ||||
|  | ||||
| cisco/client-auto-handoff: 0 | ||||
|  | ||||
| cisco/lwelem14: .x000001000000000000000000000000000000 | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										5
									
								
								src/ac/rpc-macros/telnet-off.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/ac/rpc-macros/telnet-off.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| # | ||||
| # Managed by acTube | ||||
| # | ||||
|  | ||||
| cisco/ap-telnet-ssh/telnet: false | ||||
							
								
								
									
										5
									
								
								src/ac/rpc-macros/telnet-on.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/ac/rpc-macros/telnet-on.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| # | ||||
| # Managed by acTube | ||||
| # | ||||
|  | ||||
| cisco/ap-telnet-ssh/telnet: true | ||||
							
								
								
									
										3
									
								
								src/ac/rpc-macros/txp.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/ac/rpc-macros/txp.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| radio.0/capwap80211/tx-power/@cisco/cfg-type: 1 - global | ||||
| radio.0/capwap80211/tx-power/current-tx-power: 1 | ||||
|  | ||||
							
								
								
									
										17
									
								
								src/ac/rpc-macros/wlan.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/ac/rpc-macros/wlan.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| radio.0/wlan.1/capwap80211/capability: 1073 | ||||
| radio.0/wlan.1/capwap80211/qos: 0 | ||||
| radio.0/wlan.1/capwap80211/ssid: tubeC | ||||
| radio.0/wlan.1/cisco/aironet-ie: true | ||||
| radio.0/wlan.1/cisco/broadcast-ssid: true | ||||
| radio.0/wlan.1/cisco/dtim-period: 1 | ||||
| radio.0/wlan.1/cisco/encryption-policy: 4 | ||||
| radio.0/wlan.1/cisco/hreap-local-switch: 0 | ||||
| radio.0/wlan.1/cisco/profile-name: tubeC | ||||
| radio.0/wlan.1/cisco/scan-defer-period: 28784 | ||||
| radio.0/wlan.1/cisco/scan-defer-time: 100 | ||||
| radio.0/wlan.1/cisco/session-timout: 1800 | ||||
| radio.0/wlan.1/cisco/wep-encryption: false | ||||
| radio.0/wlan.1/cisco/wep-key: .xc3e9d4b1360d7cf5bcfc759753 | ||||
| radio.0/wlan.1/cisco/wep-key-index: 1 | ||||
| radio.0/wlan.1/radio-id: 0 | ||||
| radio.0/wlan.1/wlan-id: 1 | ||||
							
								
								
									
										14
									
								
								src/ac/rpc-macros/wlan1.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/ac/rpc-macros/wlan1.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| radio.0/wlan.1/capwap80211/capability: 1057 | ||||
| radio.0/wlan.1/capwap80211/ssid: actube | ||||
| radio.0/wlan.1/cisco/allow-aaa-override: 0 | ||||
| radio.0/wlan.1/cisco/broadcast-ssid: true | ||||
| radio.0/wlan.1/cisco/dtim-period: 1 | ||||
| radio.0/wlan.1/cisco/encryption-policy: 16777216 | ||||
| radio.0/wlan.1/cisco/max-stations: 200 | ||||
| radio.0/wlan.1/cisco/profile-name: ACTUBE | ||||
| radio.0/wlan.1/cisco/session-timout: 1800 | ||||
| radio.0/wlan.1/cisco/wep-encryption: 0 | ||||
| radio.0/wlan.1/cisco/wep-key: .x00000000000000000000000000 | ||||
| radio.0/wlan.1/radio-id: 0 | ||||
| radio.0/wlan.1/wlan-id: 1 | ||||
|  | ||||
							
								
								
									
										18
									
								
								src/ac/rpc-macros/wlan13.ckv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/ac/rpc-macros/wlan13.ckv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| radio.0/wlan.13/capwap80211/capability: 1057 | ||||
| radio.0/wlan.13/capwap80211/qos: 0 | ||||
| radio.0/wlan.13/capwap80211/ssid: SuperSSID | ||||
| radio.0/wlan.13/cisco/aironet-ie: true | ||||
| radio.0/wlan.13/cisco/broadcast-ssid: true | ||||
| radio.0/wlan.13/cisco/dtim-period: 19 | ||||
| radio.0/wlan.13/cisco/encryption-policy: 1 | ||||
| radio.0/wlan.13/cisco/hreap-local-switch: 16 | ||||
| radio.0/wlan.13/cisco/profile-name: SuerWLAN | ||||
| radio.0/wlan.13/cisco/scan-defer-period: 15420 | ||||
| radio.0/wlan.13/cisco/scan-defer-time: 100 | ||||
| radio.0/wlan.13/cisco/session-timout: 1800 | ||||
| radio.0/wlan.13/cisco/wep-encryption: false | ||||
| radio.0/wlan.13/cisco/wep-key: .x55d80f0e2bf5223dd10f82407b | ||||
| radio.0/wlan.13/cisco/wep-key-index: 1 | ||||
| radio.0/wlan.13/radio-id: 0 | ||||
| radio.0/wlan.13/wlan-id: 13 | ||||
|  | ||||
							
								
								
									
										372
									
								
								src/ac/rpc.c
									
									
									
									
									
								
							
							
						
						
									
										372
									
								
								src/ac/rpc.c
									
									
									
									
									
								
							| @ -2,6 +2,7 @@ | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
| #include <ctype.h> | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| @ -16,6 +17,7 @@ | ||||
| #include "cw/log.h" | ||||
| #include "cw/dbg.h" | ||||
|  | ||||
| #include "wtpman.h" | ||||
|  | ||||
| #include "cw/connlist.h" | ||||
|  | ||||
| @ -64,6 +66,11 @@ int wlan0_cmd(struct rpcdata *sd, const char * cmd); | ||||
| int exit_cmd(struct rpcdata *sd, const char * cmd); | ||||
| int prompt_cmd(struct rpcdata *sd, const char * cmd); | ||||
| int global_cfg_cmd(struct rpcdata *sd, const char * cmd); | ||||
| int status_cmd(struct rpcdata *sd, const char * cmd); | ||||
| void print_mw(FILE *f, int w, const char * str); | ||||
| int clear_cmd(struct rpcdata *sd, const char *cmd); | ||||
| int load_cmd(struct rpcdata *sd, const char *cmd); | ||||
| int save_cmd(struct rpcdata *sd, const char *cmd); | ||||
|  | ||||
| //void show_cfg (FILE *out, mavl_t ktv); | ||||
| int show_aps (FILE *out); | ||||
| @ -88,6 +95,11 @@ static struct command cmdlist[]={ | ||||
| 	{"set", set_cmd }, | ||||
| 	{"wlan0",wlan0_cmd}, | ||||
| 	{"global_cfg", global_cfg_cmd}, | ||||
| 	{"status",status_cmd}, | ||||
| 	{"clear",clear_cmd}, | ||||
| 	{"load",load_cmd}, | ||||
| 	{"save",save_cmd}, | ||||
|  | ||||
|  | ||||
| 	{"@prompt",prompt_cmd}, | ||||
|  | ||||
| @ -112,9 +124,18 @@ int prompt_cmd(struct rpcdata *sd, const char *cmd) | ||||
| } | ||||
|  | ||||
|  | ||||
| int global_cfg_cmd(struct rpcdata *sd, const char *cmd) | ||||
| int global_cfg_cmd(struct rpcdata *sd, const char *str) | ||||
| { | ||||
| 	cw_cfg_fdump(sd->out,sd->global_cfg); | ||||
| 	char *s; | ||||
| 	while( isspace( *str ) )   | ||||
| 		 str++;  | ||||
| 	s=(char*)str; | ||||
| 	while (!isspace(*s) && *s!=0) | ||||
| 		s++; | ||||
| 	*s=0; | ||||
|  | ||||
|  | ||||
| 	cw_cfg_fdump(sd->out,sd->global_cfg,str); | ||||
| 	finish_cmd(sd->out); | ||||
| 	return 0; | ||||
| } | ||||
| @ -138,10 +159,6 @@ int list_cmd(struct rpcdata *sd, const char *cmd) | ||||
|  | ||||
| int exit_cmd(struct rpcdata *sd, const char *cmd) | ||||
| { | ||||
| 		//fprintf(sd->out,"Unknown command: '%s'\n\r\n\r",cmd); | ||||
|  | ||||
| //	printf("Exitcmd %s\n",cmd); | ||||
| 	//fprintf(sd->out,"END: %s\n\r",cmd); | ||||
| 	finish_cmd(sd->out); | ||||
| 	fflush(sd->out); | ||||
| 	return 1; | ||||
| @ -149,8 +166,18 @@ int exit_cmd(struct rpcdata *sd, const char *cmd) | ||||
|  | ||||
|  | ||||
|  | ||||
| int cfg_cmd(struct rpcdata *sd, const char *cmd) | ||||
| int cfg_cmd(struct rpcdata *sd, const char *str) | ||||
| { | ||||
| 	char *s; | ||||
| 	while( isspace( *str ) )   | ||||
| 		 str++;  | ||||
| 	s=(char*)str; | ||||
| 	while (!isspace(*s) && *s!=0) | ||||
| 		s++; | ||||
| 	*s=0; | ||||
|  | ||||
|  | ||||
|  | ||||
| 	struct cw_Conn * conn; | ||||
| 	wtplist_lock(); | ||||
| 	conn = find_ap(sd->prompt); | ||||
| @ -158,37 +185,111 @@ int cfg_cmd(struct rpcdata *sd, const char *cmd) | ||||
| 		fprintf(sd->out,"WTP '%s' not found\n",sd->prompt); | ||||
| 	} | ||||
| 	else { | ||||
| 		cw_cfg_fdump(sd->out,conn->remote_cfg); | ||||
| 		cw_cfg_fdump(sd->out,conn->remote_cfg,str); | ||||
| 	} | ||||
| 	finish_cmd(sd->out); | ||||
| 	wtplist_unlock(); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int ucfg_cmd(struct rpcdata *sd, const char *cmd) | ||||
|  | ||||
| int status_cmd(struct rpcdata *sd, const char *cmd) | ||||
| { | ||||
| //	struct cw_Conn * conn; | ||||
| 	stop(); | ||||
| //	show_cfg(sd->out,sd->update_cfg); | ||||
| 	struct cw_Conn * conn; | ||||
| 	int i; | ||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | ||||
|  | ||||
| 	wtplist_lock(); | ||||
| 	print_mw(sd->out,8,"Radio"); | ||||
| 	print_mw(sd->out,15,"Admin State"); | ||||
| 	print_mw(sd->out,15,"Oper State"); | ||||
| 	print_mw(sd->out,13,"Cause"); | ||||
| 	fprintf(sd->out,"\n"); | ||||
|  | ||||
| 	conn = find_ap(sd->prompt); | ||||
| 	if (conn==NULL){ | ||||
| 		fprintf(sd->out,"WTP '%s' not found\n",sd->prompt); | ||||
| 		goto errX; | ||||
| 	} | ||||
|  | ||||
| 	i=0; | ||||
| 	do { | ||||
| 		char tmp[128]; | ||||
| 		sprintf(key,"radio.%d",i); | ||||
| 		if (!cw_cfg_base_exists(conn->remote_cfg,key)) | ||||
| 			break; | ||||
|  | ||||
| 		sprintf(tmp,"%d",i); | ||||
| 		print_mw(sd->out,8,tmp); | ||||
|  | ||||
| 		sprintf(key,"radio.%d/capwap/admin-state",i); | ||||
| 		print_mw(sd->out,15, cw_cfg_get(conn->remote_cfg,key,"?")); | ||||
| 		sprintf(key,"radio.%d/capwap/operational-state/state",i); | ||||
| 		print_mw(sd->out,15, cw_cfg_get(conn->remote_cfg,key,"?")); | ||||
| 		sprintf(key,"radio.%d/capwap/operational-state/cause",i); | ||||
| 		print_mw(sd->out,13, cw_cfg_get(conn->remote_cfg,key,"?")); | ||||
| 		fprintf(sd->out,"\n"); | ||||
|  | ||||
| 		i++;	 | ||||
| 	}while(1); | ||||
|  | ||||
| errX:	 | ||||
| 	finish_cmd(sd->out); | ||||
| 	wtplist_unlock(); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int ucfg_cmd(struct rpcdata *sd, const char *str) | ||||
| { | ||||
| 	char *s; | ||||
| 	while( isspace( *str ) )   | ||||
| 		 str++;  | ||||
| 	s=(char*)str; | ||||
| 	while (!isspace(*s) && *s!=0) | ||||
| 		s++; | ||||
| 	*s=0; | ||||
|  | ||||
|  | ||||
| 	cw_cfg_fdump(sd->out,sd->update_cfg,str); | ||||
| 	finish_cmd(sd->out); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int clear_cmd(struct rpcdata *sd, const char *cmd) | ||||
| { | ||||
| 	cw_cfg_clear(sd->update_cfg); | ||||
| 	fprintf(sd->out,"ucfg cleard\n"); | ||||
| 	finish_cmd(sd->out); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #include "wtpman.h" | ||||
|  | ||||
| int | ||||
| send_cmd(struct rpcdata * sd, const char *cmd) | ||||
| { | ||||
|  | ||||
| 	struct wtpman * wtpman; | ||||
| 	struct cw_Conn * conn; | ||||
| 	wtplist_lock(); | ||||
| 	conn = find_ap(sd->prompt); | ||||
| 	if (conn==NULL){ | ||||
| 		fprintf(sd->out,"WTP '%s' not found\n",sd->prompt); | ||||
| 		goto errX; | ||||
| 	} | ||||
| 	else { | ||||
| 		conn->update_cfg=sd->update_cfg; | ||||
| 		wtpman=conn->data; | ||||
| 		cw_cfg_copy(sd->update_cfg,conn->update_cfg,0,NULL); | ||||
| 		wtpman->update=1; | ||||
|  | ||||
| 		fprintf(sd->out, "Sending update cmd\n"); | ||||
|  | ||||
| 	} | ||||
| errX:	 | ||||
| 	wtplist_unlock(); | ||||
| 	finish_cmd(sd->out); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -205,8 +306,6 @@ wlan0_cmd(struct rpcdata * sd, const char *cmd) | ||||
| 	} | ||||
| 	else { | ||||
| 		FILE *f=fopen("wlan0.ktv","r"); | ||||
| //		cw_ktv_read_file(f,sd->update_cfg,conn->msgset->types_tree); | ||||
| 		//conn->update_cfg=sd->update_cfg; | ||||
| 		fclose(f); | ||||
| 	} | ||||
| 	wtplist_unlock(); | ||||
| @ -217,62 +316,78 @@ int set_cmd(struct rpcdata *sd, const char *str) | ||||
| { | ||||
|  | ||||
| 	cw_Cfg_t *cfg; | ||||
|  | ||||
| 	cfg = cw_cfg_create(); | ||||
|  | ||||
| 	cw_cfg_read_from_string(str,cfg); | ||||
|  | ||||
| 	cw_cfg_fdump(sd->out,cfg); | ||||
| 	cw_cfg_fdump(sd->out,cfg,NULL); | ||||
| 	cw_cfg_copy(cfg,sd->update_cfg,DBG_CFG_UPDATES,"rpc ucfg"); | ||||
|  | ||||
| 	cw_cfg_destroy(cfg); | ||||
|  | ||||
| 	finish_cmd(sd->out); | ||||
|  | ||||
| //	cw_ktv_init_str_reader(&r,str,strlen(str)); | ||||
| 	 | ||||
| //	cw_ktv_parse_string(&r,key,type,val); | ||||
| 	/*cw_ktv_parse_string(key,type,val, 2048);*/ | ||||
| 	 | ||||
| //	fprintf(sd->out,"%s %s\n",key,val); | ||||
| //	cw_ktv_add(sd->update_cfg,key,CW_TYPE_STR,NULL,val,strlen(val)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int load_cmd(struct rpcdata *sd, const char *str) | ||||
| { | ||||
| 	char fn[CW_CFG_MAX_KEY_LEN]; | ||||
| 	int rc; | ||||
| 	const char * dir=cw_cfg_get(sd->global_cfg,"actube/rpc/macros-dir","./rpc-macros"); | ||||
|  | ||||
| 	sprintf(fn,"%s/%s.ckv",dir,str); | ||||
| 	rc= cw_cfg_load(fn,sd->update_cfg); | ||||
|  | ||||
| 	if (rc){ | ||||
| 		fprintf(sd->out,"Error loading %s: %s\n",fn,strerror(rc)); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	finish_cmd(sd->out); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int save_cmd(struct rpcdata *sd, const char *str) | ||||
| { | ||||
| 	char fn[CW_CFG_MAX_KEY_LEN]; | ||||
| 	int rc; | ||||
| 	const char * dir=cw_cfg_get(sd->global_cfg,"actube/rpc/macros-dir","./rpc-macros"); | ||||
|  | ||||
| 	sprintf(fn,"%s/%s.ckv",dir,str); | ||||
| 	rc= cw_cfg_save(fn,sd->update_cfg,"#\n# Managed by acTube\n#\n\n"); | ||||
|  | ||||
| 	if (rc){ | ||||
| 		fprintf(sd->out,"Error saving %s: %s\n",fn,strerror(rc)); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	finish_cmd(sd->out); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int del_cmd(struct rpcdata *sd, const char *str) | ||||
| { | ||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | ||||
| 	sscanf(str,"%s",key); | ||||
| 	stop(); | ||||
| //	cw_ktv_del_sub(sd->update_cfg,key); | ||||
| // | ||||
| 	char *s; | ||||
|  | ||||
| 	while( isspace( *str ) )   | ||||
| 		 str++;  | ||||
| 	s=(char*)str; | ||||
| 	while (!isspace(*s) && *s!=0) | ||||
| 		s++; | ||||
| 	*s=0; | ||||
|  | ||||
|  | ||||
| 	fprintf(sd->out,"DEL: '%s'\n",str); | ||||
| 	cw_cfg_del(sd->update_cfg,str); | ||||
| 	finish_cmd(sd->out); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
| void show_cfg (FILE *out, mavl_t ktv) | ||||
| { | ||||
| 	char value[500]; | ||||
| 	struct cw_Val * data; | ||||
| 	mavliter_t it; | ||||
| 	const struct cw_Type * type; | ||||
| 	 | ||||
| 	 | ||||
| 	mavliter_init(&it,ktv); | ||||
|  | ||||
| 	mavliter_foreach(&it){ | ||||
| 		 | ||||
| 		data = mavliter_get(&it); | ||||
| 		type = data->type; | ||||
| 		type->to_str(data,value,0); | ||||
| 		 | ||||
| 		fprintf(out,"%s :%s: %s\n",data->key,type->get_type_name(data), value); | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| } | ||||
| */ | ||||
|  | ||||
|  | ||||
| void print_mw(FILE *f, int w, const char * str) | ||||
| { | ||||
| 	int n,i; | ||||
| @ -358,62 +473,6 @@ struct cw_Conn * find_ap(const char *name) | ||||
| } | ||||
|  | ||||
|  | ||||
| void con (FILE *out) | ||||
| { | ||||
| 	stop(); | ||||
|  | ||||
| /*	 | ||||
| 	struct connlist * cl; | ||||
| 	mavliter_t it; | ||||
| 	 | ||||
| 	 | ||||
| 	 | ||||
| 	wtplist_lock(); | ||||
| 	 | ||||
| 	cl = wtplist_get_connlist(); | ||||
| 	 | ||||
| 	 | ||||
| 	mavliter_init (&it, cl->by_addr); | ||||
| 	fprintf (out, "IP\t\t\twtp-name\n"); | ||||
| 	mavliter_foreach (&it) { | ||||
| 		cw_Val_t * result; | ||||
| 		char addr[SOCK_ADDR_BUFSIZE]; | ||||
| 		char wtp_name[CAPWAP_MAX_WTP_NAME_LEN]; | ||||
| 		struct cw_Conn * conn; | ||||
| 		conn = mavliter_get_ptr (&it); | ||||
| 		 | ||||
| 		sock_addr2str_p (&conn->addr, addr); | ||||
| 		 | ||||
| 		result = cw_ktv_get (conn->remote_cfg, "wtp-name", NULL); | ||||
| 		 | ||||
| 		if (result == NULL) { | ||||
| 			strcpy (wtp_name, ""); | ||||
| 			 | ||||
| 		} else { | ||||
| 			result->type->to_str (result, wtp_name, CAPWAP_MAX_WTP_NAME_LEN); | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		fprintf (out, "Con!! %s\t\t%s\n", addr, wtp_name); | ||||
| 		 | ||||
| 		{ | ||||
| 			stop(); | ||||
|  | ||||
| 			mavl_t update; | ||||
| //			update = cw_ktv_create(); | ||||
| //			cw_ktv_set_byte(update,"radio.255/admin-state",1); | ||||
| //			conn->update_cfg=update; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		fprintf(out,"\n"); | ||||
|  | ||||
| 	} | ||||
| 	wtplist_unlock(); | ||||
| 	*/ | ||||
| } | ||||
|  | ||||
|  | ||||
| struct command * find_cmd(const char *cmd) | ||||
| { | ||||
| 	struct command * search,*result; | ||||
| @ -438,7 +497,6 @@ int execute_cmd (struct rpcdata * sd, const char *str) | ||||
| 	char cmd[1024]; | ||||
| 	char args[1024]; | ||||
| 	int n; | ||||
| 	struct cw_Val_Reader reader; | ||||
| 	struct command * searchcmd; | ||||
|  | ||||
| 	args[0]=0; | ||||
| @ -450,7 +508,19 @@ int execute_cmd (struct rpcdata * sd, const char *str) | ||||
| 	searchcmd = find_cmd(cmd); | ||||
| 	if (searchcmd!=NULL){ | ||||
| 		if (searchcmd->fun != NULL){ | ||||
| 			return searchcmd->fun(sd, str+strlen(cmd)); | ||||
| 			char *args; | ||||
| 			int n; | ||||
| 		      	args = (char*)(str+strlen(cmd)); | ||||
| 			while( isspace( *args ) )   | ||||
| 				 args++;  | ||||
| 			n = strlen(args); | ||||
| 			n--; | ||||
|  | ||||
| 			while (n>=0 && isspace(args[n])) | ||||
| 				n--; | ||||
| 			args[n+1]=0; | ||||
|  | ||||
| 			return searchcmd->fun(sd, args); | ||||
| 		} | ||||
| 	} | ||||
| 	else{ | ||||
| @ -460,73 +530,8 @@ int execute_cmd (struct rpcdata * sd, const char *str) | ||||
|  | ||||
| 	return 0; | ||||
| 	 | ||||
| 	 | ||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | ||||
| 	char type[128]; | ||||
| 	char val[2048]; | ||||
|  | ||||
| 	key[0]=0; | ||||
| 	type[0]=0; | ||||
| 	val[0]=0; | ||||
|  | ||||
| 	stop(); | ||||
| //	cw_ktv_init_str_reader(&reader,str, strlen(str)); | ||||
| //	n = cw_ktv_parse_string(&reader, key,type,val); | ||||
| 	 | ||||
| 	if (n==-1){ | ||||
| 		int i; | ||||
| 		fprintf(sd->out,"Error on pos %d\n",reader.pos); | ||||
| 		fprintf(sd->out,"%s",str); | ||||
| 		for(i=0;i<reader.pos;i++){ | ||||
| 			fprintf(sd->out," "); | ||||
| 		} | ||||
| 		fprintf(sd->out,"^\n"); | ||||
| 		fprintf(sd->out,"%s\n",reader.error); | ||||
| 	} | ||||
| 	else{ | ||||
| 		fprintf(sd->out,"%s :%s: %s\n", key,type,val); | ||||
| 	} | ||||
| 	return 0; | ||||
| 	 | ||||
| 	 | ||||
| 	n = sscanf (str, "%s%s", cmd, args); | ||||
|  | ||||
| 	if (n<=0) | ||||
| 		return 0; | ||||
| 	/*printf("CMD: %s, ARGS:\n",cmd);*/ | ||||
| 	 | ||||
| 	if (strcmp (cmd, "s") == 0) { | ||||
| 		show_aps (sd->out); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	if (strcmp (cmd, "con")==0){ | ||||
| 		con(sd->out); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| struct esc_strings { | ||||
| 	char *str; | ||||
| 	char * result; | ||||
| }; | ||||
|  | ||||
| struct esc_strings estr[] = { | ||||
| 	{"\x1b[H", "home"}, | ||||
| 	{"\x1b[F", "end"}, | ||||
| 	{"\x1b[A", "up"}, | ||||
| 	{"\x1b[B", "donw"}, | ||||
| 	{"\x1b[D", "left"}, | ||||
| 	{"\x1b[C", "right"}, | ||||
|  | ||||
| 	{NULL,NULL} | ||||
|  | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| void rpc_loop (FILE *file, cw_Cfg_t *global_cfg) | ||||
| @ -540,6 +545,7 @@ void rpc_loop (FILE *file, cw_Cfg_t *global_cfg) | ||||
| 	sd.in = file; | ||||
| 	sd.out = file;	 | ||||
| 	sd.global_cfg=global_cfg; | ||||
| 	sd.update_cfg=cw_cfg_create(); | ||||
|  | ||||
|  | ||||
| 	sprintf(sd.prompt,"%s","*"); | ||||
| @ -591,9 +597,6 @@ void * run_rpc_server (void * arg) | ||||
| 			close (clientsock); | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		 | ||||
| 		//cw_dbg (DBG_INFO,"Accepting shell session %i, %s", rc, strerror (errno)); | ||||
| 	}	 | ||||
| 	 | ||||
| 	return NULL; | ||||
| @ -633,8 +636,6 @@ int create_tcp_fd(const char *name) | ||||
| } | ||||
| static int create_unix_fd(const char *name) | ||||
| { | ||||
|         //struct sockaddr_storage client; | ||||
| 	//socklen_t client_size; | ||||
| 	struct sockaddr_un addr; | ||||
| 	int rc,fd; | ||||
|  | ||||
| @ -648,7 +649,6 @@ static int create_unix_fd(const char *name) | ||||
| 		cw_log (LOG_ERR, "Can't bind socket 'unix:%s', %s", name, strerror (errno)); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	//int clientsock = accept (fd, (struct sockaddr*) &client, &client_size); | ||||
|  | ||||
| 	return fd; | ||||
| } | ||||
| @ -657,7 +657,7 @@ int start_rpc(cw_Cfg_t *global_cfg) | ||||
| { | ||||
| 	struct sockdata * sockdata; | ||||
| 	const char *sockname; | ||||
| 	int rc; //, type; | ||||
| 	int rc;  | ||||
| 	int fd; | ||||
|  | ||||
| 	rc = cw_cfg_get_bool(global_cfg,"actube/rpc/enable",1); | ||||
|  | ||||
							
								
								
									
										320
									
								
								src/ac/wtpman.c
									
									
									
									
									
								
							
							
						
						
									
										320
									
								
								src/ac/wtpman.c
									
									
									
									
									
								
							| @ -44,6 +44,8 @@ | ||||
|  | ||||
| #include "actube.h" | ||||
|  | ||||
| #include "cw/dot11.h" | ||||
|  | ||||
|  | ||||
| static void wtpman_remove(struct wtpman *wtpman) | ||||
| { | ||||
| @ -298,6 +300,59 @@ int cw_run_state_machine(struct cw_Conn *conn, time_t * timer) | ||||
|  | ||||
| /*#define CW_TRANSITION(prestate,state) (prestate<<16|state)*/ | ||||
|  | ||||
|  | ||||
| int run_update(struct wtpman *wtpman) | ||||
| { | ||||
| 	int rc; | ||||
| 	if (!wtpman->update) | ||||
| 		return EAGAIN; | ||||
| 	rc = cw_send_request(wtpman->conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST); | ||||
|         cw_cfg_clear(wtpman->conn->update_cfg); | ||||
| 	wtpman->update=0; | ||||
| 	return rc; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static int dataman_process_msg(struct cw_Conn *nc, uint8_t * rawmsg, int len, | ||||
| 			struct sockaddr *from) | ||||
| { | ||||
| 	int offs =  cw_get_hdr_msg_offset(rawmsg); | ||||
| 	uint8_t * dot11frame = rawmsg + offs; | ||||
| 	int dot11len = len-offs; | ||||
| 	cw_dbg_dot11_frame(dot11frame,dot11len); | ||||
|  | ||||
| 	char frame[1000]; | ||||
| 	dot11_init_assoc_resp(frame); | ||||
|  | ||||
| 	dot11_copy_mac(dot11_get_sa(dot11frame),dot11_get_da(frame)); | ||||
| 	dot11_copy_mac(dot11_get_bssid(dot11frame),dot11_get_bssid(frame)); | ||||
| 	dot11_copy_mac(dot11_get_da(dot11frame),dot11_get_sa(frame)); | ||||
| 	dot11_set_seq(frame,0); | ||||
| 	 | ||||
| 	 | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void *wtpman_data_main(void *arg) | ||||
| { | ||||
| 	struct wtpman * wtpman = arg; | ||||
| 	struct cw_Conn * nc = wtpman->dconn; | ||||
| 	nc->process_packet=conn_process_packet; | ||||
| 	nc->process_message=dataman_process_msg; | ||||
|  | ||||
|  | ||||
| 	while (1){ | ||||
| 		time_t timer = cw_timer_start(2); | ||||
| 		while (!cw_timer_timeout(timer)){ | ||||
| 			cw_read_messages(nc); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
| } | ||||
|  | ||||
| static void *wtpman_main(void *arg) | ||||
| { | ||||
| 	//mavl_t r; | ||||
| @ -343,6 +398,7 @@ static void *wtpman_main(void *arg) | ||||
| 	conn->capwap_prevstate = CAPWAP_STATE_DTLS_SETUP; | ||||
| 	conn->capwap_state = CAPWAP_STATE_JOIN; | ||||
| 	rc = 0; | ||||
| 	wtpman->update=0; | ||||
|  | ||||
| 	while (1) { | ||||
|  | ||||
| @ -359,59 +415,25 @@ static void *wtpman_main(void *arg) | ||||
|  | ||||
|  | ||||
| 		while (!cw_timer_timeout(timer)) { | ||||
| 			rc = run_update(wtpman); | ||||
| 			if (rc !=EAGAIN) | ||||
| 				break; | ||||
|  | ||||
| 			rc = cw_read_messages(wtpman->conn); | ||||
| 			 | ||||
| 			if (rc < 0) { | ||||
| 				if (errno == EAGAIN) | ||||
| 				if (errno == EAGAIN){ | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		if (rc < 0) { | ||||
| 			conn->capwap_prevstate = conn->capwap_state; | ||||
| 			conn->capwap_state = CAPWAP_STATE_TIMEOUT; | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	/* dtls is established, goto join state */ | ||||
| /* | ||||
| 	conn->capwap_state = CAPWAP_STATE_JOIN; | ||||
| 	if (!wtpman_join(wtpman)) { | ||||
| 		wtpman_remove(wtpman); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| 	cw_dbg(DBG_INFO, "WTP from %s has joined with session id: %s", | ||||
| 	       sock_addr2str_p(&conn->addr, sock_buf), | ||||
| 	       format_bin2hex(conn->session_id, 16)); | ||||
|  | ||||
| */ | ||||
|  | ||||
| 	exit(0); | ||||
|  | ||||
| 	return NULL; | ||||
| @ -433,72 +455,114 @@ void wtpman_destroy(struct wtpman *wtpman) | ||||
|  | ||||
| static void copy(struct cw_ElemHandlerParams * params) | ||||
| { | ||||
| //	struct wtpman * wtpman; | ||||
| 	//struct cw_Conn * conn; | ||||
| 	//wtpman = (struct wtpman*)params->conn->data; | ||||
| 	//conn = (struct cw_Conn*)params->conn; | ||||
|  | ||||
|  | ||||
| //	cw_dbg(DBG_X,"-------------  Here is the config we ve got from WTP ---------------- "); | ||||
| //	cw_cfg_dump(params->cfg); | ||||
| //	cw_dbg(DBG_X,"-------------  This was the config we ve got from WTP ---------------- "); | ||||
| //	cw_dbg(DBG_X,"Now copying:"); | ||||
| //	cw_cfg_copy(params->cfg,conn->local_cfg,0,""); | ||||
|         cw_cfg_copy(params->cfg, params->conn->remote_cfg,DBG_CFG_UPDATES,"GlobalCfg"); | ||||
|  | ||||
| //	cw_dbg(DBG_X,"Copying done."); | ||||
| } | ||||
|  | ||||
| static int discovery_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len) | ||||
| static void catch_cfg(struct cw_ElemHandlerParams * params, int create, const char *format, ...) | ||||
| { | ||||
| 	struct cw_Conn * conn = (struct cw_Conn*)params->conn; | ||||
| 	const char *wtpname; | ||||
| 	char filename[200]; | ||||
| 	FILE *f; | ||||
| 	cw_Cfg_t * cfg_list[3]; | ||||
|  | ||||
| 	if (!cw_cfg_get_bool(params->conn->global_cfg,"actube/save-initial-wtp-config",0)) | ||||
| 		return; | ||||
|  | ||||
| 	cfg_list[0]=params->cfg; | ||||
| 	cfg_list[1]=params->conn->remote_cfg; | ||||
| 	cfg_list[2]=NULL; | ||||
|  | ||||
| 	wtpname = cw_cfg_get_l(cfg_list,"capwap/wtp-name","default"); | ||||
| 	sprintf(filename,"wtp-initial-%s.ckv",wtpname); | ||||
|  | ||||
| 	if (create)		 | ||||
| 		f = fopen(filename,"w"); | ||||
| 	else | ||||
| 		f = fopen(filename,"a"); | ||||
| 	if (f==NULL) | ||||
| 		return; | ||||
|  | ||||
| 	if (create) | ||||
| 		fprintf(f,"#\n# Initial config for WTP '%s' - catched by ACTube\n#\n\n",wtpname); | ||||
|  | ||||
|         if (format !=NULL){ | ||||
|                 va_list args; | ||||
|                 va_start(args,format); | ||||
|                 vfprintf(f,format,args); | ||||
|                 va_end(args); | ||||
|         } | ||||
| 	cw_cfg_write_to_file(f, params->cfg); | ||||
| 	fclose(f); | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static int discovery_cb(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data * d) | ||||
| { | ||||
|  | ||||
| 	cw_dbg(DBG_X,"DISCOVERY Callback"); | ||||
| 	copy(params); | ||||
| 	catch_cfg(params,1,"\n#\n# Discovery Request\n#\n"); | ||||
|  | ||||
| 	const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default"); | ||||
| 	sprintf(filename,"wtp-discovery-%s.ckv",wtpname); | ||||
| 	cw_cfg_save(filename,params->cfg,NULL); | ||||
| 	cw_cfg_clear(params->cfg); | ||||
| 		 | ||||
| 	if (d->parent) | ||||
| 		return d->parent->fun(params,d->parent); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int join_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len) | ||||
| static int join_cb(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data *d) | ||||
| { | ||||
| 	struct cw_Conn * conn = (struct cw_Conn*)params->conn; | ||||
| 	char filename[200]; | ||||
|  | ||||
| 	cw_dbg(DBG_X,"JOIN Callback"); | ||||
| 	copy(params); | ||||
| 	const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default"); | ||||
| 	sprintf(filename,"wtp-join-%s.ckv",wtpname); | ||||
| 	cw_cfg_save(filename,params->cfg,NULL); | ||||
| 	cw_cfg_clear(params->cfg); | ||||
| 	catch_cfg(params,0,"\n#\n# Join Request\n#\n"); | ||||
| 	if (d->parent) | ||||
| 		return d->parent->fun(params,d->parent); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int update_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len) | ||||
|  | ||||
| /* | ||||
| static int fill_update_cfg(struct cw_Conn * conn) | ||||
| { | ||||
| 	struct cw_Conn * conn = (struct cw_Conn*)params->conn; | ||||
| 	char filename[200]; | ||||
| 	struct cw_Cfg_iter cfi; | ||||
| 	struct cw_Cfg_entry *e; | ||||
| 	cw_Cfg_t * u; | ||||
| 	u=cw_cfg_create(); | ||||
| 	if( cw_cfg_load("status_response.ckv",u)){ | ||||
| 		cw_log(LOG_ERR,"Cant load file"); | ||||
| 		stop(); | ||||
| 	}; | ||||
| 	cw_cfg_dump(conn->remote_cfg); | ||||
|         cw_cfg_iter_init(u, &cfi, NULL); | ||||
| 	while ((e = cw_cfg_iter_next(&cfi, NULL))!=NULL){ | ||||
| 		const char * r; | ||||
| 		r = cw_cfg_get(conn->remote_cfg, e->key, "[]"); | ||||
| 	//	cw_dbg(DBG_CFG_UPDATES,"check: %s: %s",e->key,e->val); | ||||
| 		if (strcmp(r,e->val)==0) | ||||
| 			continue; | ||||
|  | ||||
| 		cw_dbg(DBG_CFG_UPDATES,"Status reps: %s: %s -> %s",e->key,r,e->val); | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
| 	cw_dbg(DBG_X,"UPDATE Callback"); | ||||
| 	copy(params); | ||||
| 	return 0; | ||||
| } | ||||
| */ | ||||
|  | ||||
| 	const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default"); | ||||
| 	sprintf(filename,"wtp-status-%s.ckv",wtpname); | ||||
| 	cw_cfg_save(filename,params->cfg,NULL); | ||||
| //stop();	 | ||||
| static int cfg_status_cb(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data *d) | ||||
| { | ||||
| 	catch_cfg(params,0,"\n#\n# Configuration Status Request\n#\n"); | ||||
| 	if (d->parent) | ||||
| 		return d->parent->fun(params,d->parent); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int event_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len) | ||||
| static int event_cb(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data *d) | ||||
| { | ||||
| 	struct cw_Conn * conn = (struct cw_Conn*)params->conn; | ||||
| 	struct wtpman * wtpman = (struct wtpman *)conn->data; | ||||
|  | ||||
| 	char filename[200]; | ||||
|  | ||||
|  | ||||
| @ -507,9 +571,26 @@ static int event_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, i | ||||
| 	copy(params); | ||||
|  | ||||
| 	const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default"); | ||||
| 	sprintf(filename,"wtp-event-%s.ckv",wtpname); | ||||
| 	cw_cfg_save(filename,conn->remote_cfg,NULL); | ||||
| //stop();	 | ||||
| 	sprintf(filename,"wtp-event-%d-%s.ckv",wtpman->ctr++,wtpname); | ||||
| 	cw_cfg_save(filename,params->cfg,NULL); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int change_state_event_cb(struct cw_ElemHandlerParams * params,struct cw_MsgCb_data * d) | ||||
| { | ||||
| 	struct cw_Conn * conn = (struct cw_Conn*)params->conn; | ||||
| 	struct wtpman * wtpman = (struct wtpman *)conn->data; | ||||
|  | ||||
| 	char filename[200]; | ||||
|  | ||||
|  | ||||
| 	 | ||||
| 	cw_dbg(DBG_X,"WTP EVENT Callback"); | ||||
| 	copy(params); | ||||
|  | ||||
| 	const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default"); | ||||
| 	sprintf(filename,"wtp-change-event-%d-%s.ckv",wtpman->ctr++,wtpname); | ||||
| 	cw_cfg_save(filename,params->cfg,NULL); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -522,7 +603,7 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | ||||
| { | ||||
| 	struct sockaddr dbgaddr; | ||||
| 	socklen_t dbgaddrl; | ||||
| 	int sockfd, replyfd; | ||||
| 	int sockfd, replyfd, data_sockfd,data_replyfd; | ||||
| 	char sock_buf[SOCK_ADDR_BUFSIZE]; | ||||
|  | ||||
| 	struct wtpman *wtpman; | ||||
| @ -530,10 +611,13 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | ||||
| 	if (!wtpman) | ||||
| 		return 0; | ||||
|  | ||||
| 	wtpman->ctr=0; | ||||
|  | ||||
| 	if (socklist[socklistindex].type != SOCKLIST_UNICAST_SOCKET) { | ||||
|  | ||||
| 		int port = sock_getport(&socklist[socklistindex].addr); | ||||
| 		replyfd = socklist_find_reply_socket(srcaddr, port); | ||||
| 		data_replyfd=replyfd; | ||||
|  | ||||
| 		if (replyfd == -1) { | ||||
| 			cw_log(LOG_ERR, | ||||
| @ -544,10 +628,11 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | ||||
| 		} | ||||
| 	} else { | ||||
| 		replyfd = socklist[socklistindex].sockfd; | ||||
| 		data_replyfd = socklist[socklistindex].data_sockfd; | ||||
| 	} | ||||
|  | ||||
| 	sockfd = replyfd;	/*//socklist[socklistindex].reply_sockfd; */ | ||||
|  | ||||
| 	data_sockfd = data_replyfd; | ||||
|  | ||||
| 	dbgaddrl = sizeof(dbgaddr); | ||||
| 	getsockname(sockfd, &dbgaddr, &dbgaddrl); | ||||
| @ -565,6 +650,21 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | ||||
| 		wtpman_destroy(wtpman); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	wtpman->dconn = cw_conn_create(data_sockfd, srcaddr, 100); | ||||
| 	if (!wtpman->dconn) { | ||||
| 		wtpman_destroy(wtpman); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| 	cw_conn_register_msg_cb(wtpman->conn, | ||||
| 		CAPWAP_MSG_DISCOVERY_REQUEST, | ||||
| 		discovery_cb); | ||||
|  | ||||
|  | ||||
| 	wtpman->conn->global_cfg = global_cfg; | ||||
| 	wtpman->conn->local_cfg = cw_cfg_create(); | ||||
| 	wtpman->wtp_cfg = cw_cfg_create(); | ||||
| @ -572,6 +672,7 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | ||||
|  | ||||
| 	wtpman->conn->role = CW_ROLE_AC; | ||||
| 	wtpman->conn->data=wtpman; | ||||
| 	wtpman->dconn->data=wtpman; | ||||
|  | ||||
| 	wtpman->conn->cfg_list[0]=wtpman->conn->update_cfg; | ||||
| 	wtpman->conn->cfg_list[1]=wtpman->conn->remote_cfg; | ||||
| @ -584,23 +685,6 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | ||||
| 	sock_copyaddr(&wtpman->conn->data_addr, | ||||
| 		      (struct sockaddr *) &wtpman->conn->addr); | ||||
|  | ||||
| 	cw_conn_set_msg_cb(wtpman->conn, | ||||
| 			CAPWAP_MSG_DISCOVERY_REQUEST, | ||||
| 			discovery_cb); | ||||
|  | ||||
| 	cw_conn_set_msg_cb(wtpman->conn, | ||||
| 			CAPWAP_MSG_JOIN_REQUEST, | ||||
| 			join_cb); | ||||
|  | ||||
| 	cw_conn_set_msg_cb(wtpman->conn, | ||||
| 			CAPWAP_MSG_CONFIGURATION_STATUS_REQUEST, | ||||
| 			update_cb); | ||||
|  | ||||
| 	cw_conn_set_msg_cb(wtpman->conn, | ||||
| 			CAPWAP_MSG_WTP_EVENT_REQUEST, | ||||
| 			event_cb); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //	wtpman->conn->mods = conf_mods; | ||||
| @ -634,15 +718,37 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | ||||
| 			       cmod->name, bmod->name); | ||||
| 			wtpman->conn->msgset = | ||||
| 			    cw_mod_get_msg_set(wtpman->conn, cmod, bmod); | ||||
|  | ||||
| 			wtpman->dconn->msgset=wtpman->conn->msgset; | ||||
| 			wtpman->conn->detected = 1; | ||||
| 			cmod->setup_cfg(wtpman->conn); | ||||
| //	               if (wtpman->conn->setup_complete) | ||||
| //        	                wtpman->conn->setup_complete(wtpman->conn); | ||||
|  | ||||
|  | ||||
| 			cw_conn_register_msg_cb(wtpman->conn, | ||||
| 				CAPWAP_MSG_JOIN_REQUEST, | ||||
| 				join_cb); | ||||
|  | ||||
| 		cw_conn_register_msg_cb(wtpman->conn, | ||||
| 				CAPWAP_MSG_CONFIGURATION_STATUS_REQUEST, | ||||
| 				cfg_status_cb); | ||||
|  | ||||
| 		cw_conn_register_msg_cb(wtpman->conn, | ||||
| 				CAPWAP_MSG_WTP_EVENT_REQUEST, | ||||
| 				event_cb); | ||||
|  | ||||
| /*		cw_conn_register_msg_cb(wtpman->conn, | ||||
| 				CAPWAP_MSG_CHANGE_STATE_EVENT_REQUEST, | ||||
| 				change_state_event_cb);*/ | ||||
|  | ||||
|  | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| 	cw_dbg(DBG_X,"WTPMAN_CREATED: %p",wtpman); | ||||
|  | ||||
| 	return wtpman; | ||||
| @ -651,7 +757,6 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | ||||
|  | ||||
| void wtpman_addpacket(struct wtpman *wtpman, uint8_t * packet, int len) | ||||
| { | ||||
| //	cw_dbg(DBG_X,"ADD PACKET DETECTED %d",wtpman->conn->detected); | ||||
| 	conn_q_add_packet(wtpman->conn, packet, len); | ||||
| } | ||||
|  | ||||
| @ -660,5 +765,14 @@ void wtpman_start(struct wtpman *wtpman, int dtlsmode) | ||||
| 	cw_dbg(DBG_INFO, "Starting wtpman, DTLS mode = %d", dtlsmode); | ||||
| 	wtpman->dtlsmode = dtlsmode; | ||||
| 	pthread_create(&wtpman->thread, NULL, wtpman_main, (void *) wtpman); | ||||
| 	pthread_create(&wtpman->thread, NULL, wtpman_data_main, (void *) wtpman); | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| void wtpman_datapacket(struct wtpman *wtpman, uint8_t * packet, int len) | ||||
| { | ||||
| 	conn_q_add_packet(wtpman->dconn, packet, len); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -17,6 +17,7 @@ struct wtpman { | ||||
| 	pthread_t thread; | ||||
|  | ||||
| 	struct cw_Conn *conn; | ||||
| 	struct cw_Conn *dconn; | ||||
|  | ||||
|  | ||||
| 	/* wtp data */ | ||||
| @ -40,8 +41,13 @@ struct wtpman { | ||||
|  | ||||
| 	cw_Cfg_t * wtp_cfg; | ||||
|  | ||||
| 	 | ||||
| 	cw_Cfg_t * discovery_cfg; | ||||
| 	cw_Cfg_t * join_cfg; | ||||
| 	cw_Cfg_t * config_status_cfg; | ||||
|  | ||||
|  | ||||
| 	int update;	 | ||||
| 	int ctr; | ||||
| }; | ||||
|  | ||||
| /* | ||||
| @ -62,6 +68,7 @@ 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); | ||||
| void wtpman_datapacket(struct wtpman *wtpman, uint8_t * packet, int len); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										5
									
								
								src/contrib/install_hostapd.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/contrib/install_hostapd.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| wget https://w1.fi/releases/hostapd-2.10.tar.gz | ||||
| tar xzvf hostapd-2.10.tar.gz | ||||
|  | ||||
| @ -6,9 +6,6 @@ CWSRC=\ | ||||
| 	cw.c\ | ||||
| 	cw_check_missing_mand.c\ | ||||
| 	cw_clock_lap.c\ | ||||
| 	cw_dbg_elem.c\ | ||||
| 	cw_dbg_set_level.c\ | ||||
| 	cw_dbg_set_level_from_str.c\ | ||||
| 	cw_filename.c\ | ||||
| 	cw_format_dump.c\ | ||||
| 	cw_format_pkt_hdr.c\ | ||||
| @ -18,13 +15,11 @@ CWSRC=\ | ||||
| 	cw_in_capwap_local_ipv4_address.c\ | ||||
| 	cw_in_capwap_local_ipv6_address.c\ | ||||
| 	cw_in_generic_with_index.c\ | ||||
| 	cw_in_radio_generic_struct.c\ | ||||
| 	cw_in_idx_generic.c\ | ||||
| 	cw_in_idx_generic_struct.c\ | ||||
| 	cw_in_generic_indexed_enum.c\ | ||||
| 	cw_out_generic_indexed_enum.c\ | ||||
| 	cw_in_generic_enum.c\ | ||||
| 	cw_out_generic_struct.c\ | ||||
| 	cw_out_idx_generic_struct.c\ | ||||
| 	cw_init_data_keep_alive_msg.c\ | ||||
| 	cw_inline.c\ | ||||
| @ -37,7 +32,6 @@ CWSRC=\ | ||||
| 	cw_put_elem_radio_operational_state.c\ | ||||
| 	cw_put_image_data.c\ | ||||
| 	cw_put_local_ip_address.c\ | ||||
| 	cw_radio_set_admin_state.c\ | ||||
| 	cw_rand.c\ | ||||
| 	cw_randint.c\ | ||||
| 	cw_read_ac_descriptor.c\ | ||||
| @ -62,11 +56,12 @@ CWSRC=\ | ||||
| 	cw_type_ipaddress.c\ | ||||
| 	cw_type_word.c\ | ||||
| 	cw_type_sysptr.c\ | ||||
| 	cw_type_array.c\ | ||||
| 	cw_type_bits.c\ | ||||
| 	cw_write_descriptor_subelem.c\ | ||||
| 	cw_write_radio_element.c\ | ||||
| 	cw_detect_nat.c\ | ||||
| 	cw_read_from.c \ | ||||
| 	cw_in_generic_struct.c\ | ||||
|  | ||||
| #	cw_in_check_disc_req.c\ | ||||
| #	cw_in_check_img_data_req_ac.c\ | ||||
| @ -77,46 +72,16 @@ CWSRC=\ | ||||
| #	cw_out_generic.c\ | ||||
| #	 | ||||
| #	cw_process_element.c\ | ||||
| #	cw_out_generic_struct.c\ | ||||
| 	cw_in_radio_generic_struct.c\ | ||||
| 	cw_in_generic_struct.c\ | ||||
| 	cw_radio_set_admin_state.c\ | ||||
| 	cw_dbg_elem.c\ | ||||
|  | ||||
| KTVSRC=\ | ||||
| 	cfg.c\ | ||||
|  | ||||
|  | ||||
| #	cw_ktv_add.c\ | ||||
| 	cw_ktv_idx_get.c\ | ||||
| 	cw_ktv_mavlcmp.c\ | ||||
| 	cw_ktv_mavlcmp_type_by_name.c\ | ||||
| 	cw_ktv_mavldel.c\ | ||||
|  | ||||
|  | ||||
| #	cw_ktv_parser.c\ | ||||
| #	cw_ktv_del_sub.c\ | ||||
| #	cw_ktv_base_exists.c\ | ||||
| 	cw_ktv_add_from_str.c\ | ||||
| 	cw_ktv_read_file.c\ | ||||
| 	cw_ktv_readline.c\ | ||||
| 	cw_ktv_save.c\ | ||||
| 	cw_ktv_std_types.c\ | ||||
| 	cw_ktv_read_struct.c\ | ||||
| 	cw_ktv_write_struct.c\ | ||||
|  | ||||
| #	cw_ktv_get_byte.c\ | ||||
| 	cw_ktv_get_bool.c\ | ||||
| 	cw_ktv_get_bstr16.c\ | ||||
| 	cw_ktv_set_byte.c\ | ||||
| 	cw_ktv_set_word.c\ | ||||
| 	cw_ktv_set_dword.c\ | ||||
|  | ||||
| #	cw_ktv_get_word.c\ | ||||
| 	cw_ktv_get_dword.c\ | ||||
| 	cw_ktv_get_sysptr.c\ | ||||
| 	cw_ktv_get_str.c\ | ||||
|  | ||||
| #	cw_ktv_cast.c\ | ||||
| 	cw_ktv_replace.c\ | ||||
| 	cw_ktv_get.c\ | ||||
|  | ||||
|  | ||||
| LWSRC=\ | ||||
| 	lw_addelem.c\ | ||||
| 	lw_checksum.c\ | ||||
| @ -169,7 +134,8 @@ LOGSRC=\ | ||||
| 	log_errno.c\ | ||||
| 	log_syslog.c\ | ||||
| 	dbg.c\ | ||||
| 	dbg_strings.c\ | ||||
|  | ||||
| #	dbg_strings.c\ | ||||
|  | ||||
| MISCSRC=\ | ||||
| 	bstr16_create.c\ | ||||
| @ -205,7 +171,6 @@ MISCSRC=\ | ||||
| 	msgset.c\ | ||||
| 	send.c\ | ||||
| 	strheap.c\ | ||||
| 	netconn.c\ | ||||
| 	conn.c \ | ||||
| 	val.c \ | ||||
| 	discovery.c\ | ||||
| @ -222,6 +187,7 @@ MISCSRC=\ | ||||
| #	cw_put_msg.c\ | ||||
| #	conn_process_packet.c\ | ||||
| #	conn_destroy.c\ | ||||
| 	netconn.c\ | ||||
|  | ||||
| DTLSSRC+=\ | ||||
| 	dtls_bio.c\ | ||||
|  | ||||
| @ -465,9 +465,9 @@ enum cw_reboot_failure_types { | ||||
| /**  | ||||
|  * The Missing AC List Result Code is sent by the  | ||||
|  * WTP to the AC when the AC List is missing */ | ||||
| #define CW_RESULT_MISSING_AC_LIST				1 | ||||
| #define CAPWAP_RESULT_SUCCESS_NAT				2 | ||||
| #define CW_RESULT_JOIN_FAILURE					3 | ||||
| #define CW_RESULT_MISSING_AC_LIST					1 | ||||
| #define CAPWAP_RESULT_SUCCESS_NAT					2 | ||||
| #define CAPWAP_RESULT_JOIN_FAILURE					3 | ||||
| #define CW_RESULT_JOIN_RESOURCE_DEPLETION			4 | ||||
| #define CW_RESULT_JOIN_UNKNOWN_SOURCE				5 | ||||
| #define CW_RESULT_JOIN_INCORRECT_DATA				6 | ||||
| @ -491,7 +491,7 @@ enum cw_reboot_failure_types { | ||||
|       13 Configuration Failure (Unable to Apply Requested Configuration | ||||
|          - Service Not Provided) | ||||
| */ | ||||
| #define CAPWAP_RESULT_CONFIGURATION_FAILURE_SERVICE_NOT PROVIDED	13 | ||||
| #define CAPWAP_RESULT_CONFIGURATION_FAILURE_SERVICE_NOT_PROVIDED	13 | ||||
| /**  | ||||
|  * Image Data Error (Invalid Checksum) | ||||
|  */ | ||||
|  | ||||
| @ -86,12 +86,15 @@ enum radioelems { | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** IEEE 802.11 Radio Information Message Element */ | ||||
| #define CAPWAP80211_ELEM_WTP_RADIO_INFORMATION		1048 | ||||
|  | ||||
| /** IEEE 802.11 Add WLAN Message element */ | ||||
| #define	CAPWAP80211_ELEM_ADD_WLAN			1024 | ||||
| /** IEEE 802.11 Antenna Message element */ | ||||
| #define CAPWAP80211_ELEM_ANTENNA			1025 | ||||
|  | ||||
|  | ||||
| /** IEEE 802.11 WTP Radio Configuration */ | ||||
| #define CAPWAP80211_ELEM_WTP_RADIO_CONFIGURATION	1046 | ||||
| /** IEEE 802.11 Radio Information Message Element */ | ||||
| #define CAPWAP80211_ELEM_WTP_RADIO_INFORMATION		1048 | ||||
|  | ||||
|  | ||||
| /** | ||||
|  | ||||
							
								
								
									
										185
									
								
								src/cw/cfg.c
									
									
									
									
									
								
							
							
						
						
									
										185
									
								
								src/cw/cfg.c
									
									
									
									
									
								
							| @ -80,7 +80,13 @@ static void del(void *ptr) | ||||
| 	free((void *) e->val); | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Create an empty cfg | ||||
|  * @return A pointer to the cfg or NULL if an error has accoured. | ||||
|  * | ||||
|  * In case of an error consult errno to find out the reason. | ||||
|  * The created config must be freed by #cw_cfg_destroy. | ||||
|  */ | ||||
| cw_Cfg_t *cw_cfg_create() | ||||
| { | ||||
| 	cw_Cfg_t * cfg; | ||||
| @ -88,6 +94,7 @@ cw_Cfg_t *cw_cfg_create() | ||||
| 	if (cfg == NULL) | ||||
| 		return NULL; | ||||
| 	memset(cfg,0,sizeof(cw_Cfg_t)); | ||||
| 	cfg->name = CW_CFG_DEFAULT_NAME; | ||||
| 	cfg->cfg = mavl_create(cmp, del, sizeof(struct cw_Cfg_entry)); | ||||
| 	if (cfg->cfg==NULL){ | ||||
| 		cw_cfg_destroy(cfg); | ||||
| @ -122,6 +129,16 @@ int cw_cfg_set(cw_Cfg_t * cfg, const char *key, const char *val) | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| void cw_cfg_del(cw_Cfg_t * cfg, const char *key) | ||||
| { | ||||
| 	struct cw_Cfg_entry e; | ||||
| 	e.key = key; | ||||
| 	e.val=NULL; | ||||
| 	mavl_del(cfg->cfg,&e); | ||||
| } | ||||
|  | ||||
|  | ||||
| const char *cw_cfg_get(cw_Cfg_t * cfg, const char *key, const char *def) | ||||
| { | ||||
| 	struct cw_Cfg_entry e, *r; | ||||
| @ -137,7 +154,6 @@ const char *cw_cfg_get_l(cw_Cfg_t ** cfg, const char * key, const char *def) | ||||
| 	int i; | ||||
| 	struct cw_Cfg_entry e, *r; | ||||
| 	for(i=0; cfg[i]!=NULL; i++){ | ||||
| //		cw_dbg(DBG_X,"GET_L IN: %p",cfg[i]); | ||||
| 		e.key = key; | ||||
| 		r = mavl_get(cfg[i]->cfg, &e); | ||||
| 		if (r!=NULL) | ||||
| @ -160,11 +176,29 @@ bstr16_t cw_cfg_get_bstr16(cw_Cfg_t * cfg, const char * key, const char *def) | ||||
|  | ||||
| 	s = cw_cfg_get(cfg,key,def); | ||||
| 	if(s==NULL) | ||||
| 		s=def; | ||||
| 	if (s==NULL) | ||||
| 		return NULL; | ||||
|  | ||||
| 	return bstr16_create_from_str(s); | ||||
| } | ||||
|  | ||||
| bstr16_t cw_cfg_get_bstr16_l(cw_Cfg_t **cfgs, const char * key, const char *def) | ||||
| { | ||||
| 	bstr16_t s; | ||||
| 	int i; | ||||
|  | ||||
| 	for(i=0; cfgs[i]!=NULL; i++){ | ||||
| 		s = cw_cfg_get_bstr16(cfgs[i],key,NULL); | ||||
| 		if (s!=NULL) | ||||
| 			return s; | ||||
| 	} | ||||
| 	if (def == NULL) | ||||
| 		return NULL; | ||||
| 	return bstr16_create_from_str(def); | ||||
|  | ||||
| } | ||||
|  | ||||
| int cw_cfg_set_bstr16(cw_Cfg_t * cfg, const char * key, bstr16_t str) | ||||
| { | ||||
| 	CW_TYPE_BSTR16->read(cfg,key,bstr16_data(str),bstr16_len(str),NULL); | ||||
| @ -186,7 +220,7 @@ void cw_cfg_dump(cw_Cfg_t * cfg) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg) | ||||
| void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg, const char *filter) | ||||
| { | ||||
| 	mavliter_t it; | ||||
| 	struct cw_Cfg_entry *e; | ||||
| @ -194,6 +228,13 @@ void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg) | ||||
| 	mavliter_foreach(&it) { | ||||
|  | ||||
| 		e = mavliter_get(&it); | ||||
| 		if (filter != NULL){ | ||||
| 			if (strlen(filter)){ | ||||
| 				if (strstr(e->key,filter)==NULL){ | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		fprintf(f,"%s: '%s'\n", e->key, e->val); | ||||
| 	} | ||||
| } | ||||
| @ -487,6 +528,7 @@ int cw_cfg_load(const char *filename, cw_Cfg_t * cfg) | ||||
| 	FILE *f = fopen(filename, "rb"); | ||||
| 	if (!f) | ||||
| 		return errno; | ||||
| 	errno=0; | ||||
| 	errs = cw_cfg_read_from_file(f, cfg); | ||||
| 	fclose(f); | ||||
|  | ||||
| @ -559,7 +601,12 @@ void cw_cfg_iter_init(cw_Cfg_t * cfg, struct cw_Cfg_iter *cfi, const char *base) | ||||
| 	search.key = base; | ||||
|  | ||||
| 	mavliter_init(&(cfi->it), cfg->cfg); | ||||
| 	mavliter_seek(&(cfi->it), &search, 0); | ||||
| 	if (base == NULL){ | ||||
| 		mavliter_seek_set(&(cfi->it)); | ||||
| 		mavliter_next(&(cfi->it)); | ||||
| 	} | ||||
| 	else | ||||
| 		mavliter_seek(&(cfi->it), &search, 0); | ||||
| 	cfi->base = base; | ||||
| } | ||||
|  | ||||
| @ -568,16 +615,16 @@ struct cw_Cfg_entry *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *nnkey | ||||
| { | ||||
| 	struct cw_Cfg_entry *e; | ||||
| 	int bl, kl; | ||||
| 	const char *d; | ||||
|  | ||||
| //	const char *d; | ||||
| 	e = mavliter_get(&(cfi->it)); | ||||
| 	if (e == NULL) | ||||
| 	if (e == NULL){ | ||||
| 		return NULL; | ||||
|  | ||||
| 	} | ||||
| 	if (cfi->base ==NULL) | ||||
| 		goto eeX; | ||||
|  | ||||
| 	bl = strlen(cfi->base); | ||||
| 	kl = strlen(e->key); | ||||
|  | ||||
| 	if (bl > kl) | ||||
| 		return NULL; | ||||
|  | ||||
| @ -590,16 +637,19 @@ struct cw_Cfg_entry *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *nnkey | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
| 	d = strchr(e->key, '.'); | ||||
| 	if (d == NULL) | ||||
|  | ||||
| 	if (e->key[bl]!='.' && e->key[bl]!='/') | ||||
| 		return NULL; | ||||
|  | ||||
| 	if (d - e->key != bl) | ||||
| /*	d = strchr(e->key, '.'); | ||||
| 	if (d == NULL) | ||||
| 		return NULL; | ||||
| 	if (d - e->key != bl) | ||||
| 		return NULL;*/ | ||||
|  | ||||
| 	if (strncmp(cfi->base, e->key, bl) != 0) | ||||
| 		return NULL; | ||||
|  | ||||
| eeX: | ||||
| 	mavliter_next(&(cfi->it)); | ||||
| 	return e; | ||||
| } | ||||
| @ -615,7 +665,13 @@ int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, int def) | ||||
| 	return v.val.boolean; | ||||
| } | ||||
|  | ||||
| /* | ||||
| int cw_cfg_set_bool(cw_Cfg_t * cfg, const char * key, int val) | ||||
| { | ||||
| 	return cw_cfg_set(cfg,key,val ? "true":"false"); | ||||
| } | ||||
|  | ||||
| */ | ||||
| uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def) | ||||
| { | ||||
| 	struct cw_Val v; | ||||
| @ -638,6 +694,14 @@ uint8_t cw_cfg_get_byte_l(cw_Cfg_t ** cfgs, char *key, uint8_t def) | ||||
| 	return v.val.byte; | ||||
| } | ||||
|  | ||||
| int cw_cfg_get_int(cw_Cfg_t * cfg, const char *key, int def) | ||||
| { | ||||
| 	const char *s = cw_cfg_get(cfg,key,NULL); | ||||
| 	if (s==NULL) | ||||
| 		return def; | ||||
| 	return atoi(s); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, const char *key, uint16_t def) | ||||
| @ -662,7 +726,6 @@ uint16_t cw_cfg_get_word_l(cw_Cfg_t ** cfg, const char *key, uint16_t def) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
| int cw_cfg_get_word(cw_Cfg_t * cfg, char *key, const char * def) | ||||
| { | ||||
| @ -682,8 +745,7 @@ void cw_cfg_set_int(cw_Cfg_t * cfg, const char * key, int val) | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key) | ||||
| int cw_cfg_get_new_index(cw_Cfg_t * cfg, const char *key) | ||||
| { | ||||
| 	char ikey[CW_CFG_MAX_KEY_LEN]; | ||||
| 	struct cw_Cfg_entry search, * result; | ||||
| @ -699,7 +761,7 @@ int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key) | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	d = strchr(result->key,'.'); | ||||
| 	d = strrchr(result->key,'.'); | ||||
| 	if (d==NULL){ | ||||
| 		return 0; | ||||
| 	} | ||||
| @ -710,6 +772,46 @@ int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key) | ||||
| 	return atoi(d+1)+1; | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_cfg_get_first_index(cw_Cfg_t * cfg, const char *key, int n) | ||||
| { | ||||
| 	char ikey[CW_CFG_MAX_KEY_LEN]; | ||||
| 	struct cw_Cfg_entry search, * result; | ||||
| 	char *d; | ||||
| 	int l; | ||||
| 	 | ||||
| 	sprintf(ikey,"%s.%d",key,n); | ||||
| 	search.key=ikey; | ||||
| 	 | ||||
| 	result = mavl_get_first(cfg->cfg,&search); | ||||
| 	if (result == NULL){ | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	d = strrchr(ikey,'.'); | ||||
| 	if (d==NULL){ | ||||
| 		return -1; | ||||
| 	} | ||||
| 	l = d-ikey; | ||||
| 	if (strncmp(result->key,ikey,l)!=0) | ||||
| 		return -1; | ||||
| 	 | ||||
| 	return atoi(result->key+l+1); | ||||
| } | ||||
|  | ||||
| int cw_cfg_get_first_index_l(cw_Cfg_t ** cfgs, const char *key, int n) | ||||
| { | ||||
| 	int r; | ||||
| 	while(*cfgs != NULL){ | ||||
| 		r = cw_cfg_get_first_index(*cfgs,key,n); | ||||
| 		if (r!=-1) | ||||
| 			return r; | ||||
| 		cfgs++; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *type, const void * valguard, const uint8_t * data, int len) | ||||
| { | ||||
| 	cw_Val_t mdata, *mresult; | ||||
| @ -808,22 +910,43 @@ void cw_cfg_clear(cw_Cfg_t *cfg) | ||||
| int cw_cfg_base_exists(cw_Cfg_t * cfg, const char *key) | ||||
| { | ||||
|         struct cw_Cfg_entry e, *result; | ||||
| //cw_dbg(DBG_X,"LOOX FOR: %s",key); | ||||
|         e.key=key; | ||||
|         result = mavl_get_first(cfg->cfg,&e); | ||||
|         if (result == NULL) | ||||
|                 return 0; | ||||
| //cw_dbg(DBG_X,"BASEXXX: %s",result->key); | ||||
| 	int rl,kl; | ||||
| 	char skey[CW_CFG_MAX_KEY_LEN]; | ||||
| 	char * delimiters = "/."; | ||||
| 	char * d; | ||||
|  | ||||
| 	if (strlen(result->key)<strlen(key)) | ||||
| 		return 0;		 | ||||
| //cw_dbg(DBG_X,"BASEXXX1: %d",strlen(key)); | ||||
| 	if (result->key[strlen(key)]!='/' && result->key[strlen(key)]!='.') | ||||
| 		return 0; | ||||
| //cw_dbg(DBG_X,"BASEXXX2: "); | ||||
| 	if (strncmp(result->key,key,strlen(key))==0) | ||||
| 	/* can we find the base exactly ?*/ | ||||
| 	if (cw_cfg_get(cfg,key,NULL)!=NULL) | ||||
| 		return 1; | ||||
| cw_dbg(DBG_X,"BASEXXX3: "); | ||||
|  | ||||
|  | ||||
| 	for(d=delimiters; *d!=0; d++){ | ||||
| 		sprintf(skey,"%s%c",key,*d); | ||||
|  | ||||
| 	        e.key=skey; | ||||
| 	        result = mavl_get_first(cfg->cfg,&e); | ||||
|  | ||||
| 	 | ||||
| 		/* if we've found nothing, we can't check more */ | ||||
| 	        if (result == NULL) | ||||
| 	                continue; | ||||
|  | ||||
| 		rl = strlen(result->key); | ||||
| 		kl = strlen(skey); | ||||
|  | ||||
| 		/* if result key is shorter than key */ | ||||
| 		if (rl<kl) | ||||
| 			continue; | ||||
|  | ||||
| 		/* both keys are identical in length */ | ||||
| 		if (rl==kl){ | ||||
| 			if (strcmp(result->key,key)==0) | ||||
| 				return 1; | ||||
| 		} | ||||
| 	 | ||||
| 		if (strncmp(result->key,skey,kl)==0) | ||||
| 			return 1; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										57
									
								
								src/cw/cfg.h
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								src/cw/cfg.h
									
									
									
									
									
								
							| @ -5,28 +5,53 @@ | ||||
| #include "val.h" | ||||
| #include "bstr.h" | ||||
|  | ||||
| #define CW_CFG_MAX_KEY_LEN 1024 | ||||
|  | ||||
| /** | ||||
|  *@file | ||||
|  *@brief | ||||
|  *@defgroup CFG SOCK | ||||
|  *@{ | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /** Maximum size of a key used in cfg objects */ | ||||
| #define CW_CFG_MAX_KEY_LEN 1024	 | ||||
|  | ||||
| /** Default name for fresh cfg's created by #cw_cfg_create */  | ||||
| #define CW_CFG_DEFAULT_NAME "[anonymous]" | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * A Cfg object  | ||||
|  */ | ||||
| struct cw_Cfg { | ||||
| 	struct mavl * cfg; | ||||
| 	const char *name; | ||||
| 	struct mavl * cfg;	/**< The AVL-tree containig the keys  | ||||
| 				     and vals */ | ||||
| 	const char *name;	/**< A name for this config object */ | ||||
| 	int dbg_level; | ||||
| 	const char *dbg_prefix; | ||||
| }; | ||||
|  | ||||
| typedef struct cw_Cfg cw_Cfg_t; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * An antry for a Cfg object | ||||
|  */ | ||||
| struct cw_Cfg_entry{ | ||||
| 	const char *key;	/**< A string representing the key  | ||||
| 				     of this entry */ | ||||
| 	const char *val;	/**< The value, represented by a string */ | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| cw_Cfg_t * cw_cfg_create(); | ||||
| int cw_cfg_set(cw_Cfg_t *cfg,const char *key, const char *val); | ||||
| void cw_cfg_dump(cw_Cfg_t *cfg); | ||||
| int cw_cfg_read_from_file(FILE * file, cw_Cfg_t * cfg); | ||||
| int cw_cfg_load(const char *filename,cw_Cfg_t * cfg); | ||||
|  | ||||
| struct cw_Cfg_entry{ | ||||
| 	const char *key; | ||||
| 	const char *val; | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct cw_Cfg_iter{ | ||||
| 	struct mavliter it; | ||||
| @ -44,7 +69,7 @@ void cw_cfg_set_int(cw_Cfg_t * cfg, const char * key, int val); | ||||
| uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def); | ||||
| bstr16_t cw_cfg_get_bstr16(cw_Cfg_t * cfg, const char * key, const char *def); | ||||
| int cw_cfg_set_bstr16(cw_Cfg_t * cfg, const char * key, bstr16_t str); | ||||
| int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key); | ||||
| int cw_cfg_get_new_index(cw_Cfg_t * cfg, const char *key); | ||||
| const char *cw_cfg_get_l(cw_Cfg_t ** cfg, const char * key, const char *def); | ||||
| void cw_cfg_copy(cw_Cfg_t *src, cw_Cfg_t *dst,int dbg_level,const char *dbg_prefix); | ||||
| void cw_cfg_destroy(cw_Cfg_t *cfg); | ||||
| @ -56,14 +81,23 @@ int cw_cfg_base_exists_l(cw_Cfg_t ** cfgs, const char *key); | ||||
| int cw_cfg_save(const char *filename, cw_Cfg_t *cfg, const char *format, ...); | ||||
|  | ||||
| uint16_t cw_cfg_get_word_l(cw_Cfg_t ** cfg, const char *key, uint16_t def); | ||||
| void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg); | ||||
| void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg, const char *filter); | ||||
|  | ||||
| int cw_cfg_read_from_string(const char *str, cw_Cfg_t *cfg); | ||||
| void cw_cfg_del(cw_Cfg_t * cfg, const char *key); | ||||
|  | ||||
| int cw_cfg_get_first_index(cw_Cfg_t * cfg, const char *key, int n); | ||||
| int cw_cfg_get_first_index_l(cw_Cfg_t ** cfgs, const char *key, int n); | ||||
|  | ||||
| int cw_cfg_get_int(cw_Cfg_t * cfg, const char *key, int def); | ||||
| int cw_cfg_write_to_file(FILE *f, cw_Cfg_t * cfg); | ||||
|  | ||||
| #define cw_cfg_set_bool(cfg,key,val) \ | ||||
| 		cw_cfg_set(cfg,key,(val) ? "true":"false") | ||||
|  | ||||
|  | ||||
| int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *t, const void * valguard, const uint8_t * data, int len); | ||||
| bstr16_t cw_cfg_get_bstr16_l(cw_Cfg_t **cfgs, const char * key, const char *def); | ||||
|  | ||||
| #define cw_cfg_get_word2(cfg1,cfg2,key,def) \ | ||||
| 	cw_cfg_get_word(cfg1,key,cw_cfg_get_word(cfg2,key,def)) | ||||
| @ -74,3 +108,6 @@ int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *t, con | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /**@}*/ | ||||
|  | ||||
|  | ||||
| @ -24,11 +24,12 @@ | ||||
|  | ||||
| #include "dtls.h" | ||||
|  | ||||
|  | ||||
| #define MAX_MSG_CBS 5 | ||||
|  | ||||
| struct msg_callback{ | ||||
| 	int type; /**< message type */ | ||||
| 	cw_MsgCallbackFun fun; | ||||
| 	int type; 			/**< message type */ | ||||
| 	struct cw_MsgCb_data data[MAX_MSG_CBS]; | ||||
| 	int count; | ||||
| }; | ||||
|  | ||||
| int msg_callback_cmp(const void *v1,const void *v2) | ||||
| @ -62,19 +63,55 @@ void cw_conn_init(struct cw_Conn * conn) | ||||
| 	conn->remote_cfg = cw_cfg_create(); | ||||
| 	conn->local_cfg = cw_cfg_create(); | ||||
| 	conn->cfg_list[0]=NULL; | ||||
|  | ||||
| 	conn->remote_addr[0]=0; | ||||
| } | ||||
|  | ||||
| int cw_conn_set_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun) | ||||
|  | ||||
| /** | ||||
|  * Register a message callback function.  | ||||
|  * @param conn the connection the registered cb functions belongs to | ||||
|  * @param type The associated msg type. Whenever a message of this type is  | ||||
|  *             received, the callback function will be called | ||||
|  * @param fun  A pinter to the callback function           | ||||
|  * | ||||
|  */ | ||||
| int cw_conn_register_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun) | ||||
| { | ||||
| 	struct msg_callback cb; | ||||
| 	struct msg_callback cb, *result; | ||||
| 	int exists; | ||||
|  | ||||
| 	cb.type = type; | ||||
| 	cb.fun = fun; | ||||
| 	mavl_insert(conn->msg_callbacks,&cb,&exists); | ||||
| 	cb.data[0].fun = fun; | ||||
| 	cb.data[0].parent = NULL; | ||||
| 	cb.count = 0; | ||||
|  | ||||
|  | ||||
| 	result = mavl_insert(conn->msg_callbacks,&cb,&exists); | ||||
|  | ||||
| 	cw_dbg(DBG_X, "Registering msg callback: %d %p",type,result); | ||||
|  | ||||
| 	if (result==NULL) | ||||
| 		return 0; | ||||
|  | ||||
| 	if (exists){ | ||||
| 		if (result->count>=MAX_MSG_CBS){ | ||||
| 			cw_log(LOG_ERROR,"Too many msg callback registrations for msg id %d",type); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		result->count++; | ||||
| 		result->data[result->count].fun=fun; | ||||
| 		result->data[result->count].parent=&(result->data[result->count-1]); | ||||
| 		cw_dbg(DBG_X,"The result exists: %p %p %d %p",result,&cb,result->count, | ||||
| 				result->data[result->count].parent | ||||
| 				); | ||||
| 		 | ||||
| 	} | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* | ||||
| cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type) | ||||
| { | ||||
| 	struct msg_callback cb,*result; | ||||
| @ -83,8 +120,22 @@ cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type) | ||||
| 	if (result == NULL) | ||||
| 		return NULL; | ||||
| 	return result->fun; | ||||
| }*/ | ||||
|  | ||||
|  | ||||
| int cw_conn_run_msg_cbs(struct cw_Conn * conn, int type, struct cw_ElemHandlerParams *params) | ||||
| { | ||||
| 	struct msg_callback cb,*result; | ||||
| 	cb.type=type; | ||||
| 	result = mavl_get(conn->msg_callbacks,&cb); | ||||
| 	if (result == NULL) | ||||
| 		return -1; | ||||
| 	return result->data[result->count].fun(params,&(result->data[result->count])); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Create a conn object | ||||
|  * @param sock a socket | ||||
| @ -106,8 +157,10 @@ struct cw_Conn * cw_conn_create(int sock, struct sockaddr * addr, int qsize) | ||||
|  | ||||
| 	conn->sock=sock; | ||||
|  | ||||
| 	if (addr) | ||||
| 	if (addr){ | ||||
| 		sock_copyaddr(&conn->addr,addr); | ||||
| 		sock_addr2str_p(addr, conn->remote_addr);	 | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	conn->fragman = fragman_create(); | ||||
| @ -516,12 +569,12 @@ static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len, | ||||
| 		message->postprocess(¶ms,elems_ptr, elems_len); | ||||
| 	} | ||||
|  | ||||
| 	cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type); | ||||
| 	if (cb_fun != NULL){ | ||||
| 		result_code = cb_fun(¶ms,elems_ptr, elems_len); | ||||
| 	} | ||||
| 	else{ | ||||
| 	result_code = cw_conn_run_msg_cbs(conn,message->type,¶ms); | ||||
|  | ||||
| //	cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type); | ||||
| 	if (result_code==-1){ | ||||
| 		cw_cfg_clear(conn->update_cfg); | ||||
| 		result_code=0; | ||||
| 	} | ||||
|  | ||||
| //	conn->remote_cfg=params.cfg; | ||||
| @ -554,7 +607,6 @@ static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len, | ||||
| 		 * Put further actions here, if needed. | ||||
| 		 */ | ||||
| 	} | ||||
|  | ||||
| 	if (params.unrecognized) | ||||
| 		mlist_destroy(params.unrecognized); | ||||
| 	cw_cfg_destroy(params.cfg); | ||||
| @ -713,24 +765,22 @@ int conn_process_packet2(struct cw_Conn *conn, uint8_t * packet, int len, | ||||
|  | ||||
| 	if (cw_get_hdr_flag_f(packet)) { | ||||
| 		/* fragmented, add the packet to fragman */ | ||||
| 		uint8_t *f; | ||||
| 		uint8_t *f,*fp; | ||||
| 		int rc; | ||||
|  | ||||
| 		f = fragman_add(conn->fragman, packet, offs, payloadlen); | ||||
| 		if (f == NULL) { | ||||
| 		fp = fragman_add(conn->fragman, packet, offs, payloadlen); | ||||
| 		if (fp == NULL) { | ||||
| 			errno = EAGAIN; | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		f =fp+MAX_PKT_HDR_LEN; | ||||
|  | ||||
| 		cw_dbg_pkt(DBG_PKT_IN, conn, f + 4, *(uint32_t *) f, from); | ||||
| /*//		cw_dbg_msg(DBG_MSG_IN, conn, f + 4, *(uint32_t *) f, from);*/ | ||||
|  | ||||
| /*		// XXX: Modify fragman to not throw away CAPWAP headers*/ | ||||
| 		cw_dbg_pkt(DBG_PKT_IN, conn, fp, *(uint32_t *) f+MAX_PKT_HDR_LEN, from); | ||||
|  | ||||
| 		rc = conn->process_message(conn, f + 4, *(uint32_t *) f, from); | ||||
|  | ||||
| 		free(f); | ||||
| 		free(fp); | ||||
| 		return rc; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -58,6 +58,8 @@ struct cw_action_in; | ||||
| struct cw_Conn { | ||||
| 	int sock; | ||||
| 	struct sockaddr_storage addr; | ||||
| 	char remote_addr[64];	/* Contains a printfable string, of the connections | ||||
| 				   peer address */ | ||||
|  | ||||
| 	struct connlist * connlist; | ||||
|  | ||||
| @ -71,19 +73,19 @@ struct cw_Conn { | ||||
| 	int recv_timeout; | ||||
|  | ||||
|  | ||||
| 	cw_Cfg_t * global_cfg;	/**< This should set the global cfg of the program | ||||
| 	cw_Cfg_t * global_cfg;	/**< This should set to the global cfg of the program | ||||
| 				     which is using this conn object. | ||||
| 				     Teh global_cfg has to be treated read-only. */ | ||||
|  | ||||
| 	cw_Cfg_t * local_cfg;	/**< local_cfg contains overrides for global_cfg  | ||||
| 				     wich are related to this conn object. */ | ||||
| 				     wich are related to this conniection. */ | ||||
| 	 | ||||
| 	cw_Cfg_t * remote_cfg;	/**< contains the configuration we now from the  | ||||
| 				     device this conn object ist connected to. | ||||
| 				     Typically this is what we have got from discovery | ||||
| 				     response or join response in WTP mode.  | ||||
| 				     And in AC mode this contains date receive from  | ||||
| 				     configuration status request.  */ | ||||
| 				     And in AC mode this contains datia received by  | ||||
| 				     configuration status and join request.  */ | ||||
|  | ||||
| 	cw_Cfg_t * update_cfg; | ||||
|  | ||||
| @ -311,7 +313,18 @@ int conn_send_msg(struct cw_Conn *conn, uint8_t * rawmsg); | ||||
| void conn_clear_upd(struct cw_Conn*conn, int merge); | ||||
|  | ||||
|  | ||||
| int cw_conn_set_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun); | ||||
|  | ||||
| struct cw_MsgCb_data; | ||||
| //typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len,  | ||||
| //		struct cw_MsgCb_data *d); | ||||
| typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data *d); | ||||
|  | ||||
| struct cw_MsgCb_data{ | ||||
| 	cw_MsgCallbackFun fun; | ||||
| 	struct cw_MsgCb_data * parent; | ||||
| }; | ||||
|  | ||||
| int cw_conn_register_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun); | ||||
| cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type); | ||||
|  | ||||
| int cw_decode_element(struct cw_ElemHandlerParams *params, int proto, | ||||
|  | ||||
							
								
								
									
										217
									
								
								src/cw/cw.c
									
									
									
									
									
								
							
							
						
						
									
										217
									
								
								src/cw/cw.c
									
									
									
									
									
								
							| @ -11,7 +11,7 @@ int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * | ||||
| 	char mkey[CW_CFG_MAX_KEY_LEN]; | ||||
| 	const char *key; | ||||
|  | ||||
|  | ||||
| //	cw_dbg(DBG_X,"HK: %s",handler->key,); | ||||
|  | ||||
| 	if (!type){ | ||||
| 		cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); | ||||
| @ -25,21 +25,16 @@ int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * | ||||
| 	else{ | ||||
| 		key = handler->key; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	 | ||||
|  | ||||
| /*	cw_dbg(DBG_X, "READ: %s / %s",type->name,key);*/ | ||||
| //	cw_dbg(DBG_X, "READ: %s / %s",type->name,key); | ||||
| 	type->read(params->cfg, key,elem_data,elem_len,handler->param); | ||||
| 	return CAPWAP_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst) | ||||
| int cw_out_generic0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst,const char *key) | ||||
| { | ||||
|  | ||||
| 	int start, len, l; | ||||
| 	 | ||||
| //	cw_dbg(DBG_X,"cw_out_generic (%s)%s",((struct cw_Type*)handler->type)->name,handler->key); | ||||
| @ -47,10 +42,23 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams | ||||
| //	cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); | ||||
| //	cw_cfg_dump(params->cfg); | ||||
| //	cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!! ENDDUMP"); | ||||
| // | ||||
| // | ||||
| 	if (!params->elemdata->mand){ | ||||
| 		if (!cw_cfg_base_exists(params->cfg_list[0],key)){ | ||||
| 			cw_dbg(DBG_MSG_COMPOSE,"    Add Elem: %d %d %d %s %s - (bskip)",  | ||||
| 				params->elemdata->proto,  | ||||
| 				params->elemdata->vendor,  | ||||
| 				params->elemdata->id,  | ||||
| 				handler->name, key); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	}	 | ||||
|  | ||||
|  | ||||
| 	start = params->msgset->header_len(handler); | ||||
| 	len = ((const cw_Type_t*)(handler->type))-> | ||||
| 		write(params->cfg_list,handler->key,dst+start,handler->param); | ||||
| 		write(params->cfg_list,key,dst+start,handler->param); | ||||
| //	cw_dbg(DBG_X, "Type result is %d",len); | ||||
|  | ||||
| 	if (len == -1) { | ||||
| @ -62,7 +70,7 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams | ||||
| 			cw_log(LOG_ERR, | ||||
| 			       "Can't put mandatory element %s %d-(%s) into %s. No value for '%s' found.", | ||||
| 				vendor, handler->id, handler->name, params->msgdata->name | ||||
| 			       , handler->key | ||||
| 			       , key | ||||
| 			    ); | ||||
| 		} | ||||
| 		else{ | ||||
| @ -79,6 +87,15 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams | ||||
| 	l = params->msgset->write_header(handler,dst,len); | ||||
|  | ||||
| 	return l; | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst) | ||||
| { | ||||
| 	return cw_out_generic0(handler,params,dst,handler->key); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -117,6 +134,39 @@ int cw_out_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerP | ||||
| 	int len,i,l,start; | ||||
| 	int radios; | ||||
| 	len =0; | ||||
|  | ||||
| 	for (i=0; (i=cw_cfg_get_first_index_l(params->cfg_list,"radio",i))!=-1; i++){ | ||||
| 		sprintf(key,"radio.%d/%s",i,handler->key); | ||||
| 		if (!params->elemdata->mand){ | ||||
| 			if (!cw_cfg_base_exists(params->cfg_list[0],key)){ | ||||
| 				cw_dbg(DBG_MSG_COMPOSE,"    Add Elem: %d %d %d %s %s - (skip)",  | ||||
| 						params->elemdata->proto,  | ||||
| 						params->elemdata->vendor,  | ||||
| 						params->elemdata->id,  | ||||
| 						handler->name, key); | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		type = (struct cw_Type*)handler->type; | ||||
| 		start = params->msgset->header_len(handler)+len; | ||||
|  | ||||
| 		l = type->write(params->cfg_list, key,dst+start+1,handler->param); | ||||
| 		if (l==-1) | ||||
| 			continue; | ||||
|  | ||||
| 		l += cw_put_byte(dst+start,i); | ||||
|  | ||||
| 		l = params->msgset->write_header(handler,dst+len,l); | ||||
| 		len+=l; | ||||
| 		 | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return len; | ||||
|  | ||||
|  | ||||
|  | ||||
| 	 | ||||
| 	radios = cw_cfg_get_byte_l(params->cfg_list,"capwap/wtp-descriptor/max-radios",0); | ||||
| 	for(i=0;i<radios;i++){ | ||||
| @ -270,3 +320,148 @@ cw_put_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list, | ||||
| 	 | ||||
| 	return d-dst; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
| int cw_out_traverse0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst, int i, const char *current, const char * next,  | ||||
| 			int * stack) | ||||
| { | ||||
| 	char *sl; | ||||
| 	int l; | ||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | ||||
| 	int len; | ||||
| 	len = 0; | ||||
|  | ||||
| printf("Next: %s\n", next); | ||||
|  | ||||
| 	sl = strchr(next,'/'); | ||||
| 	if (sl==NULL){ | ||||
| 		cw_Val_t * result; | ||||
| 		sprintf(key,"%s/%s",current,next); | ||||
| 		result = cw_ktv_base_exists(params->cfg,key); | ||||
| 		if (result != NULL){ | ||||
| 			int offset; | ||||
| 			int i,l; | ||||
| 			offset = params->msgset->header_len(handler); | ||||
| 			printf("Yea! We can do it: %s\n",result->key); | ||||
| 			for (i=0;i<stack[0];i++){ | ||||
| 				printf("I=%i\n",stack[i+1]); | ||||
| 			} | ||||
| 			l= cw_ktv_write_struct(params->cfg,params->cfg,  | ||||
| 				handler->type,key,dst+offset); | ||||
| 			 | ||||
| 			printf("Write struct len %i\n",l); | ||||
| 			 | ||||
| 			l=params->msgset->write_header(handler,dst,l); | ||||
| 			printf("header wr len %d\n",l); | ||||
| 			if (handler->patch){ | ||||
| 				handler->patch(dst+offset,stack); | ||||
| 			} | ||||
| 			 | ||||
| 			return l; | ||||
| 		} | ||||
| 		 | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	strcpy(key,current); | ||||
|  | ||||
| printf("current is %s\n", current);	 | ||||
|  | ||||
| 	if (key[0!=0]) | ||||
| 		strcat(key,"/"); | ||||
| 	l = sl - next; | ||||
| 	strncat(key,next,l); | ||||
| 	 | ||||
| 	 | ||||
| 	printf("Here we are %s\n",key); | ||||
| 	cw_dbg_ktv_dump(params->cfg,DBG_INFO,"start"," ", "end" ); | ||||
| 	i=-1; | ||||
| 	while(1){ | ||||
| 		char basekey[CW_CFG_MAX_KEY_LEN]; | ||||
| 		cw_Val_t * result; | ||||
| 		 | ||||
| 		i = cw_ktv_idx_get_next(params->cfg,key,i+1); | ||||
| 		 | ||||
| 		if (i==-1) | ||||
| 			break; | ||||
| 		sprintf(basekey,"%s.%d",key,i); | ||||
| 		printf("Our basekey is %s\n",basekey); | ||||
| 		result = cw_ktv_base_exists(params->cfg,basekey); | ||||
| 		if (result == NULL){ | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		stack[0]++; | ||||
| 		stack[stack[0]]=i; | ||||
| 		len += cw_out_traverse0(handler,params,dst+len,-1,basekey,next+l+1, stack); | ||||
| 		printf("Len is now %d\n", len); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	return len; | ||||
| 	 | ||||
| 	return 0; | ||||
| } | ||||
| */ | ||||
| int cw_out_traverse(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst) | ||||
|  | ||||
| { | ||||
| /*	char current[CW_CFG_MAX_KEY_LEN]; | ||||
| 	int stack[10]; | ||||
| 	stack[0]=0; | ||||
| 	current[0]=0; | ||||
| //	return cw_out_traverse0(handler,params,dst,-1,current,handler->key, stack);*/ | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int walk0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 		, uint8_t * dst, const char *current, const char * next) | ||||
| { | ||||
|         char key[CW_CFG_MAX_KEY_LEN]; | ||||
|         const char *sl; | ||||
| 	int rc; | ||||
|         int len=0; | ||||
|  | ||||
|         /* Is this the last key ? */ | ||||
|         sl = strchr(next,'/'); | ||||
|         if (sl){ | ||||
|                 char basekey[CW_CFG_MAX_KEY_LEN+13]; | ||||
|                 int i,l; | ||||
|                 strcpy(key,current); | ||||
|                 l = sl - next; | ||||
|                 strncat(key,next,l); | ||||
|  | ||||
|                 for (i=0; (i=cw_cfg_get_first_index_l(params->cfg_list,key,i))!=-1; i++){ | ||||
|                         sprintf(basekey,"%s.%d%c",key,i, *(sl+1) ?'/':'\0'); | ||||
|                         rc = walk0(handler,params,dst,basekey,next+l+1); | ||||
| 			if (rc>0) | ||||
| 				len+=rc; | ||||
|                 } | ||||
|                 return len; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         printf("Final %s [%s]\n",current,next); | ||||
| 	return cw_out_generic0(handler,params,dst,current); | ||||
|  | ||||
|         return 0; | ||||
|  | ||||
| } | ||||
|  | ||||
| int cw_out_generic_walk(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst) | ||||
| { | ||||
|         char current[CW_CFG_MAX_KEY_LEN]; | ||||
| //        int stack[10]; | ||||
|  //       stack[0]=0; | ||||
|         current[0]=0; | ||||
|  | ||||
| 	return walk0(handler,params,dst,current,handler->key); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -146,8 +146,10 @@ | ||||
|  | ||||
|  | ||||
| int cw_get_hdr_ws_len(uint8_t * th); | ||||
| uint8_t *cw_get_hdr_ws_data(uint8_t * th); | ||||
| int cw_get_hdr_ws_len_7(uint8_t * th); | ||||
|  | ||||
| uint8_t *cw_get_hdr_ws_data(uint8_t * th); | ||||
| #define cw_get_hdr_ws_data_7(th) (cw_get_hdr_ws_data(th)+1) | ||||
|  | ||||
|  | ||||
| #define cw_get_hdr_msg_offset(th) (4*cw_get_hdr_hlen(th)) | ||||
| @ -558,6 +560,10 @@ int cw_put_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list, | ||||
|  | ||||
|  | ||||
| int cw_send_request(struct cw_Conn *conn,int msg_id); | ||||
| int cw_out_generic_walk(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst); | ||||
| int cw_out_generic0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst,const char *key); | ||||
|  | ||||
| /** | ||||
|  *@} | ||||
|  | ||||
| @ -1,26 +0,0 @@ | ||||
|  | ||||
| #include "dbg.h" | ||||
|  | ||||
| /** | ||||
|   * Set debug level | ||||
|   * @param level debug level to set, allowed values are enumberated in #cw_dbg_levels structure. | ||||
|   * @param on 1: turns the specified debug level on, 0: turns the specified debug level off. | ||||
|   */ | ||||
|  | ||||
| void cw_dbg_set_level (int level, int on) | ||||
| { | ||||
| 	switch (level) { | ||||
| 		case DBG_ALL: | ||||
| 			if (on) | ||||
| 				cw_dbg_opt_level = 0xffffffff; | ||||
| 			else | ||||
| 				cw_dbg_opt_level = 0; | ||||
| 			break; | ||||
| 		default: | ||||
| 			if (on) | ||||
| 				cw_dbg_opt_level |= (level); | ||||
| 			else  | ||||
| 				cw_dbg_opt_level &= (0xffffffff) ^ (level); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,31 +0,0 @@ | ||||
|  | ||||
| #include "dbg.h" | ||||
|  | ||||
| int cw_dbg_set_level_from_str(const char *level) | ||||
| { | ||||
| 	int blevel,on; | ||||
| 	const char *slevel; | ||||
| 	 | ||||
| 	switch(*level){ | ||||
| 		case '-': | ||||
| 		case '!': | ||||
| 		case '~': | ||||
| 			on =0; | ||||
| 			slevel=level+1; | ||||
| 			break; | ||||
| 		case '+': | ||||
| 			slevel=level+1; | ||||
| 			on=1; | ||||
| 			break; | ||||
| 		default: | ||||
| 			slevel=level; | ||||
| 			on=1; | ||||
| 	} | ||||
|  | ||||
| 	blevel = cw_strlist_get_id(cw_dbg_strings, slevel); | ||||
| 	if (blevel==-1) | ||||
| 		return 0; | ||||
| 		 | ||||
| 	cw_dbg_set_level(blevel,on); | ||||
| 	return 1; | ||||
| } | ||||
| @ -3,9 +3,10 @@ | ||||
|  | ||||
| #include "dbg.h" | ||||
| #include "cw.h" | ||||
| #include "cfg.h" | ||||
|  | ||||
| /** | ||||
|  * @brief Detect NAT after a join/discovery request | ||||
|  * @brief Detect NAT after a Join Request | ||||
|  * @param conn Connection object | ||||
|  * @retval 1 NAT detected | ||||
|  * @retval 0 no NAT was detected | ||||
| @ -15,7 +16,8 @@ int cw_detect_nat(struct cw_ElemHandlerParams *params) | ||||
| 	const char  * remote_str; | ||||
| 	char local_str[128]; | ||||
|  | ||||
| 	remote_str = cw_cfg_get(params->cfg,"capwap-local-ip-address",NULL); | ||||
| 	remote_str = cw_cfg_get(params->cfg,"capwap/local-ip-address",NULL); | ||||
|  | ||||
| 	if (remote_str == NULL){ | ||||
| 		cw_dbg(DBG_WARN,"Can't detect NAT. No local IP from peer received."); | ||||
| 		return 0; | ||||
| @ -29,9 +31,12 @@ int cw_detect_nat(struct cw_ElemHandlerParams *params) | ||||
| 	 | ||||
| 	/* if connected and sent address is the same, there is  | ||||
| 	 * no NAT */ | ||||
| 	if (strcmp(remote_str,local_str)==0) | ||||
| 	if (strcmp(remote_str,local_str)==0){ | ||||
| 		cw_dbg(DBG_INFO,"Connection from %s: no NAT detected.",local_str); | ||||
| 		return 0; | ||||
| 	}		 | ||||
| 	/* otherwise ther must be something between AC and WTP */ | ||||
| 	cw_dbg(DBG_INFO,"Connection from %s: NAT detected.",local_str); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -3,105 +3,104 @@ | ||||
| #include "conn.h" | ||||
| #include "cw.h" | ||||
|  | ||||
| /** | ||||
|  * @brief Format a packet header for debugging purposes | ||||
|  * @param dst Destination buffer | ||||
|  * @param incomming True if the packet is an incomming packet, otherweise 0 | ||||
|  * @param packet packet data | ||||
|  * @param len length of packet data | ||||
|  * @param from Address from where the packet was received | ||||
|  * @return Number of bytes written | ||||
|  */ | ||||
| int cw_format_pkt_hdr(char *dst, int incomming, uint8_t * packet, int len, | ||||
| 		      struct sockaddr *from) | ||||
| #include "dot11.h" | ||||
|  | ||||
| int cw_format_dot11_fc_flags(char *dst, uint8_t *frame){ | ||||
| 	char *s = dst; | ||||
| 	uint8_t f = frame[0]; | ||||
| 	s+=sprintf(s,"ToDS:%d ", f&1 ? 1:0); | ||||
| 	s+=sprintf(s,"FromDS:%d ", f&2 ? 1:0); | ||||
| 	s+=sprintf(s,"More Frgs:%d ", f&4 ? 1:0); | ||||
| 	s+=sprintf(s,"Retry:%d ", f&8 ? 1:0); | ||||
| 	s+=sprintf(s,"PwrMgmt:%d ", f&16 ? 1:0); | ||||
| 	s+=sprintf(s,"More Dta:%d ", f&32 ? 1:0); | ||||
| 	s+=sprintf(s,"Protec:%d ", f&64 ? 1:0); | ||||
| 	s+=sprintf(s,"+HTC/:%d ", f&128 ? 1:0); | ||||
| 	return s-dst; | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_format_dot11_rates(char *dst, const uint8_t *src, int len) | ||||
| { | ||||
| 	int i; | ||||
| 	char * k=""; | ||||
| 	char *s=dst; | ||||
|  | ||||
| 	for(i=0; i<len; i++){ | ||||
| 		int rate = src[i] &0x7f; | ||||
| 		s+=sprintf(s,"%s%0.1f",k,dot11_rate2float(rate)); | ||||
| 		k=", "; | ||||
| 	} | ||||
| 	return s-dst; | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_format_dot11_elem(char *dst, uint8_t id, const uint8_t *src, int len) | ||||
| { | ||||
| 	char *s = dst; | ||||
| 	s += sprintf(s,"elem(id=%d) ",id); | ||||
|  | ||||
|  | ||||
| 	switch(id){ | ||||
| 		case DOT11_ELEM_SSID: | ||||
| 			s+=sprintf(s," ssid: %.*s",len,src); | ||||
| 			break; | ||||
| 		case DOT11_ELEM_SUPPORTED_RATES: | ||||
| 			s+=sprintf(s," Supported Rates:"); | ||||
| 			s+=cw_format_dot11_rates(s,src,len); | ||||
| 			break; | ||||
| 		case DOT11_ELEM_EXTENDED_SUPPORTED_RATES: | ||||
| 			s+=sprintf(s," Extended Supported Rates"); | ||||
| 			break; | ||||
| 		case DOT11_ELEM_POWER_CAPABILITY: | ||||
| 			s+=sprintf(s," Power Capability"); | ||||
| 			break; | ||||
| 		case DOT11_ELEM_SUPPORTED_CHANNELS: | ||||
| 			s+=sprintf(s," Supported Channels"); | ||||
| 			break; | ||||
| 		case DOT11_ELEM_SUPPORTED_OPERATING_CLASSES: | ||||
| 			s+=sprintf(s," Supported Operating Classes"); | ||||
| 			break; | ||||
| 		case DOT11_ELEM_VENDOR_SPECIFIC: | ||||
| 			s+=sprintf(s," Vendor Specific"); | ||||
| 			break; | ||||
| 	default: | ||||
| 			break; | ||||
| 	} | ||||
| 	s+=sprintf(s,", len=%d",len); | ||||
| 	return s-dst; | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_format_dot11_hdr(char * dst, uint8_t * packet, int len) | ||||
| { | ||||
| 	char sock_buf[SOCK_ADDR_BUFSIZE];  | ||||
| 	int preamble; | ||||
| 	char *s; | ||||
| 	int hlen, rid, wbid; | ||||
| 	int frag_id,frag_offs; | ||||
| 	int type = dot11_get_type_and_subtype(packet); | ||||
|  | ||||
| 	s = dst; | ||||
| 	s=dst; | ||||
|  | ||||
| 	if (incomming){ | ||||
| 		if (cw_get_hdr_flag_f(packet)) { | ||||
| 			s += sprintf(s, "Fragment from %s", | ||||
| 				     sock_addr2str_p(from,sock_buf)); | ||||
| 		} else { | ||||
| 			s += sprintf(s, "From %s", sock_addr2str_p(from,sock_buf)); | ||||
| 		} | ||||
| 	} | ||||
| 	else{ | ||||
| 		if (cw_get_hdr_flag_f(packet)) { | ||||
| 			s += sprintf(s, "Fragment to %s", sock_addr2str(from,sock_buf)); | ||||
| 		} else { | ||||
| 			s += sprintf(s, "To %s", sock_addr2str(from,sock_buf)); | ||||
| 		} | ||||
| 	} | ||||
| 	s += sprintf(s, " l=%d: ", len); | ||||
|  | ||||
| 	preamble = cw_get_hdr_preamble(packet); | ||||
| 	if (preamble == 01) { | ||||
| 		s += sprintf(s, " (encrypted)"); | ||||
| 		return s - dst; | ||||
| 	} | ||||
|  | ||||
| 	if (len < 4) | ||||
| 		goto abort; | ||||
|  | ||||
| /*		 | ||||
| 	if (cw_get_hdr_flag_f(packet)){ | ||||
| 		s+=sprintf(s," (fragmented)"); | ||||
| 	} | ||||
| */ | ||||
| 	hlen = cw_get_hdr_hlen(packet); | ||||
| 	rid = cw_get_hdr_rid(packet); | ||||
| 	wbid = cw_get_hdr_wbid(packet); | ||||
| 	s += sprintf(s, " H:%d R:%02d W:%02d", hlen, rid, wbid); | ||||
|  | ||||
|  | ||||
| 	s += sprintf(s, " Flgs:"); | ||||
| 	s += format_hdr_flags(s, packet); | ||||
|  | ||||
| 	if (len < 8) | ||||
| 		goto abort; | ||||
| 	frag_id = cw_get_hdr_fragid(packet); | ||||
| 	frag_offs = cw_get_hdr_fragoffset(packet); | ||||
| 	s += sprintf(s, " Frag/Offs:%d/%d", frag_id, frag_offs); | ||||
|  | ||||
|  | ||||
| 	if (cw_get_hdr_flag_m(packet)) { | ||||
| 		/* rmac is present, print the rmac */ | ||||
| 		int rmac_len = cw_get_hdr_rmac_len(packet); | ||||
| 		int plen = rmac_len; | ||||
| 		if (rmac_len + 8 > len) | ||||
| 			plen = len - 8; | ||||
| 		if (rmac_len > 10) | ||||
| 			plen = 10; | ||||
|  | ||||
| 		s += sprintf(s, " R-MAC:"); | ||||
| 		s += format_mac(s, cw_get_hdr_rmac_data(packet), plen); | ||||
| 		if (rmac_len > 10) { | ||||
| 			s += sprintf(s, " ... (len=%d)", rmac_len); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (cw_get_hdr_flag_w(packet)) { | ||||
| 		/* print wireless specific info */ | ||||
| 		int ws_len = cw_get_hdr_ws_len(packet); | ||||
| 		int plen = ws_len > 20 ? 20 : ws_len; | ||||
| 		s += sprintf(s, " WS:"); | ||||
| 		s += format_hexu(s, cw_get_hdr_ws_data(packet), plen); | ||||
| 		if (ws_len > 20) { | ||||
| 			s += sprintf(s, " ... (len=%d)", ws_len); | ||||
| 		} | ||||
| 	} | ||||
| 	return s - dst; | ||||
|  | ||||
|  | ||||
|  | ||||
|       abort: | ||||
| 	s += sprintf(s, " Incomplete..."); | ||||
| 	return s - dst; | ||||
| 	s+=sprintf(s,"IEEE 802.11 - %s",dot11_get_frame_name(packet)); | ||||
| 	s+=sprintf(s," da:"); | ||||
| 	s+=format_mac(s,dot11_get_da(packet),6);	 | ||||
| 	s+=sprintf(s," sa:"); | ||||
| 	s+=format_mac(s,dot11_get_sa(packet),6);	 | ||||
| 	s+=sprintf(s," bssid:"); | ||||
| 	s+=format_mac(s,dot11_get_bssid(packet),6); | ||||
| 	s+=sprintf(s," seq: %d\n",dot11_get_seq(packet)); | ||||
| 	s+=cw_format_dot11_fc_flags(s,packet); | ||||
| 	s+=sprintf(s,"\nDuration: %d",dot11_get_duration(packet)); | ||||
| // | ||||
| /*	switch (type){ | ||||
| 		case DOT11_ASSOC_REQ: | ||||
| 			s+=sprintf(s,"\n   ssid: %.*s",dot11_assoc_req_get_ssid_len(packet), | ||||
| 					dot11_assoc_req_get_ssid(packet) | ||||
| 			); | ||||
| 			break; | ||||
| 			 | ||||
| 	}*/ | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,37 +0,0 @@ | ||||
|  | ||||
| #include "capwap.h" | ||||
| #include "msgset.h" | ||||
| #include "val.h" | ||||
| #include "log.h" | ||||
| #include "dbg.h" | ||||
|  | ||||
| int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, | ||||
| 		uint8_t * elem_data, int elem_len) | ||||
| { | ||||
| 	cw_Type_t * type; | ||||
| 	type = (cw_Type_t*)handler->type; | ||||
| 	char mkey[CW_CFG_MAX_KEY_LEN]; | ||||
| 	const char *key; | ||||
|  | ||||
|  | ||||
|  | ||||
| 	if (!type){ | ||||
| 		cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); | ||||
| 		return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; | ||||
| 	} | ||||
|  | ||||
| 	if (handler->mkkey != NULL){ | ||||
| 		handler->mkkey(handler->key,elem_data,elem_len, mkey); | ||||
| 		key = mkey; | ||||
| 	} | ||||
| 	else{ | ||||
| 		key = handler->key; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	 | ||||
|  | ||||
| /*	cw_dbg(DBG_X, "READ: %s / %s",type->name,key);*/ | ||||
| 	type->read(params->cfg, key,elem_data,elem_len,handler->param); | ||||
| 	return CAPWAP_RESULT_SUCCESS; | ||||
| } | ||||
| @ -1,36 +0,0 @@ | ||||
|  | ||||
| #include "capwap.h" | ||||
| #include "msgset.h" | ||||
| #include "val.h" | ||||
| #include "log.h" | ||||
| #include "dbg.h" | ||||
|  | ||||
| int cw_in_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, | ||||
| 		uint8_t * elem_data, int elem_len) | ||||
| { | ||||
| 	cw_dbg(DBG_X,"STRUCT KEY: %s",handler->key); | ||||
| 	stop(); | ||||
| /*	const char * key; | ||||
| 	char tmpkey[CW_CFG_MAX_KEY_LEN]; | ||||
|  | ||||
| 	 | ||||
| 	if (handler->mkkey != NULL){ | ||||
| 		handler->mkkey(key,elem_data,elem_len, tmpkey); | ||||
| 		key = tmpkey; | ||||
| 	} | ||||
| 	else{ | ||||
| 		key = handler->key; | ||||
| 	} | ||||
|  | ||||
| //printf("CW_IN_GENERIC STRUCT: %s\n",key);	 | ||||
|  | ||||
|  | ||||
| 	if (!handler->type){ | ||||
| 		cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); | ||||
| 		return CAPWAP_RESULT_UNRECOGNIZED_MESSAGE_ELEMENT; | ||||
| 	} | ||||
|  | ||||
| 	cw_ktv_read_struct(params->cfg,handler->type,key,elem_data,elem_len); | ||||
| */ | ||||
| 	return CAPWAP_RESULT_SUCCESS; | ||||
| } | ||||
| @ -10,12 +10,14 @@ | ||||
| int cw_in_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, | ||||
| 		uint8_t * elem_data, int elem_len) | ||||
| { | ||||
| 	stop(); | ||||
|  | ||||
| 	/* | ||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | ||||
| 	int idx; | ||||
|  | ||||
|  | ||||
| 	cw_dbg(DBG_X,"Fix cw_in_idx_generic_struct"); | ||||
| 	stop(); | ||||
| 	 | ||||
| 	if (!handler->type){ | ||||
| 		cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); | ||||
| @ -26,6 +28,6 @@ int cw_in_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHand | ||||
| 	sprintf(key, handler->key, idx); | ||||
|  | ||||
| 	cw_ktv_read_struct(params->cfg,handler->type,key,elem_data+1,elem_len-1); | ||||
|  | ||||
| */ | ||||
| 	return CAPWAP_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| @ -15,6 +15,25 @@ int cw_get_hdr_ws_len(uint8_t * th) | ||||
| 	return *(th + 9 + cw_get_hdr_rmac_len(th)); | ||||
| } | ||||
|  | ||||
|  | ||||
| /**  | ||||
|  * Get length of wireless specific data for CAPWAP packet draft 7 | ||||
|  * @param th Pointer to packet | ||||
|  * @return length of wireless specific data | ||||
|  * | ||||
|  * Call this function only if the W flag is set | ||||
|  */ | ||||
| int cw_get_hdr_ws_len_7(uint8_t * th) | ||||
| { | ||||
| 	if (!cw_get_hdr_flag_m(th)){ | ||||
| 		return *(th + 9); | ||||
| 	} | ||||
| 	return *(th + 10 + cw_get_hdr_rmac_len(th)); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /**  | ||||
|  * Get pointer to wireless specific data | ||||
|  * @param th Pointer to packet | ||||
|  | ||||
| @ -25,16 +25,17 @@ int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemH | ||||
| 	ob = dst; | ||||
| 	 | ||||
| 	e = ie->type; | ||||
|  | ||||
|  | ||||
| 	 | ||||
| 	for(i=0; e[i].name!=NULL; i++) { | ||||
| 		int b; | ||||
| 		sprintf(key,"%s/%s",handler->key,e[i].name); | ||||
|  | ||||
| cw_dbg(DBG_X,"Her is the Key: %s %s\n",key,e[i].name); | ||||
|  | ||||
| 		b = cw_cfg_base_exists_l(params->cfg_list,handler->key); | ||||
| 		b = cw_cfg_base_exists(params->cfg_list[0],handler->key); | ||||
| 		if (!b){ | ||||
| 			stop(); | ||||
| 			//stop(); | ||||
| 			continue; | ||||
| 		} | ||||
| 		start = params->msgset->header_len(handler); | ||||
|  | ||||
| @ -1,48 +0,0 @@ | ||||
| #include "capwap.h" | ||||
| #include "msgset.h" | ||||
| #include "val.h" | ||||
| #include "log.h" | ||||
| #include "cw.h" | ||||
|  | ||||
| #include "dbg.h" | ||||
|  | ||||
|  | ||||
| int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst) | ||||
| { | ||||
| 	cw_dbg(DBG_X,"Key: %s",handler->key); | ||||
| 	stop(); | ||||
|  | ||||
|  | ||||
| 	int start; | ||||
| 	int len; | ||||
| 	cw_Val_t search, *result; | ||||
|  | ||||
| 	if (!handler->type){ | ||||
| 		cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	search.key = (char*)handler->key; | ||||
| 	result = mavl_get_first(params->cfg,&search); | ||||
| 	if (result == NULL ){ | ||||
| 		if (params->elemdata->mand) | ||||
| 			cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	if (strncmp(result->key,handler->key, strlen(handler->key))!=0){ | ||||
| 		if (params->elemdata->mand) | ||||
| 			cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	start = params->msgset->header_len(handler); | ||||
|  | ||||
| 	len = cw_ktv_write_struct(params->cfg, | ||||
| 		params->cfg, | ||||
| 		handler->type,handler->key,dst+start); | ||||
| 	 | ||||
| 	return params->msgset->write_header(handler,dst,len); | ||||
|  | ||||
| } | ||||
| @ -7,7 +7,7 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan | ||||
| { | ||||
|  | ||||
| 	stop(); | ||||
|  | ||||
| /* | ||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | ||||
| 	struct cw_Val * elem, search; | ||||
| 	int i; | ||||
| @ -26,7 +26,7 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan | ||||
| 		 | ||||
| 		sprintf(key,handler->key,i); | ||||
| 		search.key=key; | ||||
| 		/*elem = mavl_get(params->conn->local_cfg, &search);*/ | ||||
| 		/ * elem = mavl_get(params->conn->local_cfg, &search); * / | ||||
| 		elem = mavl_get_first(params->cfg,&search); | ||||
| 		if(elem != NULL){ | ||||
| 			printf("Elem key: %s\n",elem->key); | ||||
| @ -55,14 +55,16 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan | ||||
| 	 | ||||
|  | ||||
| 	 | ||||
| /*	radios = cw_ktv_get_byte(params->conn->local_cfg,"wtp-descriptor/max-radios",0); | ||||
| / *	radios = cw_ktv_get_byte(params->conn->local_cfg,"wtp-descriptor/max-radios",0); | ||||
|  | ||||
| 	for(i=1;i<radios+1;i++){ | ||||
| 		l = cw_write_radio_element(handler,params,i,dst+len); | ||||
| 		cw_dbg_elem(DBG_ELEM_OUT,params->conn,params->msgdata->type,handler,dst,l); | ||||
| 		len+=l; | ||||
| 	} | ||||
| */ | ||||
| * / | ||||
|  | ||||
| 	return mdst-dst; | ||||
| 	*/ return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -42,106 +42,8 @@ int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemH | ||||
|  | ||||
| 		cdst+=params->msgset->write_header(handler,cdst,l); | ||||
| 	} | ||||
| 	return cdst-dst; | ||||
| 	return cdst-dst;*/ | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_out_traverse0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst, int i, const char *current, const char * next,  | ||||
| 			int * stack) | ||||
| { | ||||
| 	char *sl; | ||||
| 	int l; | ||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | ||||
| 	int len; | ||||
| 	len = 0; | ||||
|  | ||||
| printf("Next: %s\n", next); | ||||
|  | ||||
| 	sl = strchr(next,'/'); | ||||
| 	if (sl==NULL){ | ||||
| 		cw_Val_t * result; | ||||
| 		sprintf(key,"%s/%s",current,next); | ||||
| 		result = cw_ktv_base_exists(params->cfg,key); | ||||
| 		if (result != NULL){ | ||||
| 			int offset; | ||||
| 			int i,l; | ||||
| 			offset = params->msgset->header_len(handler); | ||||
| 			printf("Yea! We can do it: %s\n",result->key); | ||||
| 			for (i=0;i<stack[0];i++){ | ||||
| 				printf("I=%i\n",stack[i+1]); | ||||
| 			} | ||||
| 			l= cw_ktv_write_struct(params->cfg,params->cfg,  | ||||
| 				handler->type,key,dst+offset); | ||||
| 			 | ||||
| 			printf("Write struct len %i\n",l); | ||||
| 			 | ||||
| 			l=params->msgset->write_header(handler,dst,l); | ||||
| 			printf("header wr len %d\n",l); | ||||
| 			if (handler->patch){ | ||||
| 				handler->patch(dst+offset,stack); | ||||
| 			} | ||||
| 			 | ||||
| 			return l; | ||||
| 		} | ||||
| 		 | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	strcpy(key,current); | ||||
|  | ||||
| printf("current is %s\n", current);	 | ||||
|  | ||||
| 	if (key[0!=0]) | ||||
| 		strcat(key,"/"); | ||||
| 	l = sl - next; | ||||
| 	strncat(key,next,l); | ||||
| 	 | ||||
| 	 | ||||
| 	printf("Here we are %s\n",key); | ||||
| 	cw_dbg_ktv_dump(params->cfg,DBG_INFO,"start"," ", "end" ); | ||||
| 	i=-1; | ||||
| 	while(1){ | ||||
| 		char basekey[CW_CFG_MAX_KEY_LEN]; | ||||
| 		cw_Val_t * result; | ||||
| 		 | ||||
| 		i = cw_ktv_idx_get_next(params->cfg,key,i+1); | ||||
| 		 | ||||
| 		if (i==-1) | ||||
| 			break; | ||||
| 		sprintf(basekey,"%s.%d",key,i); | ||||
| 		printf("Our basekey is %s\n",basekey); | ||||
| 		result = cw_ktv_base_exists(params->cfg,basekey); | ||||
| 		if (result == NULL){ | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		stack[0]++; | ||||
| 		stack[stack[0]]=i; | ||||
| 		len += cw_out_traverse0(handler,params,dst+len,-1,basekey,next+l+1, stack); | ||||
| 		printf("Len is now %d\n", len); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	return len; | ||||
| 	*/ | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int cw_out_traverse(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||
| 			, uint8_t * dst) | ||||
|  | ||||
| { | ||||
|  | ||||
| 	//char current[CW_CFG_MAX_KEY_LEN]; | ||||
| 	//int stack[10]; | ||||
| 	//stack[0]=0; | ||||
|  | ||||
| 	//current[0]=0; | ||||
|  | ||||
| 	stop(); | ||||
| 	return 0; | ||||
| 	 | ||||
| //	return cw_out_traverse0(handler,params,dst,-1,current,handler->key, stack); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -49,6 +49,8 @@ int cw_setup_dtls(struct cw_Conn *conn, cw_Cfg_t * cfg, const char *prefix, | ||||
| 	sprintf(key, "%s/%s", prefix, "ssl-cipher"); | ||||
| 	conn->dtls_cipher = cw_cfg_get(cfg, key, default_cipher); | ||||
|  | ||||
| 	cw_dbg(DBG_DTLS,"Using cipher: %s",conn->dtls_cipher); | ||||
|  | ||||
| 	sprintf(key, "%s/%s", prefix, "ssl-psk"); | ||||
| 	conn->dtls_psk = (bstr16_t)cw_cfg_get(cfg, key, NULL); | ||||
|  | ||||
|  | ||||
							
								
								
									
										188
									
								
								src/cw/cw_type_array.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								src/cw/cw_type_array.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,188 @@ | ||||
| /* | ||||
|     This file is part of libcapwap. | ||||
|  | ||||
|     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 <stdio.h> | ||||
|  | ||||
| #include "cw.h" | ||||
| #include "val.h" | ||||
| #include "dbg.h" | ||||
|  | ||||
| static cw_Val_t *get(cw_Val_t * data, const uint8_t * src, int len) | ||||
| { | ||||
| 	data->type = &cw_type_byte; | ||||
| 	data->val.byte = cw_get_byte(src); | ||||
| 	return data; | ||||
| } | ||||
|  | ||||
| static int put(const cw_Val_t *data, uint8_t * dst) | ||||
| { | ||||
| 	return cw_put_byte(dst, data->val.byte); | ||||
| } | ||||
|  | ||||
| static const char * get_guardstr(int val, const cw_ValValRange_t * valrange) | ||||
| { | ||||
| 	if (valrange==NULL) | ||||
| 		return NULL; | ||||
|  | ||||
| 	while(valrange->name!=NULL){ | ||||
| 		if(val>=valrange->min && val<=valrange->max) | ||||
| 			return valrange->name; | ||||
| 		valrange++; | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int to_str(const cw_Val_t *data, char *dst, int max_len) | ||||
| { | ||||
| 	if (data->valguard!=NULL){ | ||||
| 		const char * name; | ||||
| 		name = get_guardstr(data->val.byte,data->valguard); | ||||
| 		if (name != NULL){ | ||||
| 			return sprintf(dst,"%s",name); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 		/*if (max_len<3){ | ||||
| 			return 0; | ||||
| 		}*/ | ||||
| 	return sprintf(dst, "%d", data->val.byte); | ||||
|  | ||||
| } | ||||
|  | ||||
| static int get_guardval(const char *str, const cw_ValValRange_t * valrange) | ||||
| { | ||||
| 	while(valrange->name!=NULL){ | ||||
| 		if(strcmp(str,valrange->name)==0) | ||||
| 			return valrange->min; | ||||
| 		valrange++; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| static cw_Val_t *from_str(cw_Val_t * data, const char *src) | ||||
| { | ||||
| 	data->type = &cw_type_byte; | ||||
| 	if (data->valguard != NULL){ | ||||
| 		int rc; | ||||
| 		rc = get_guardval(src,data->valguard); | ||||
| 		if (rc != -1){ | ||||
| 			data->val.byte = rc; | ||||
| 			return data; | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	data->val.byte = atoi(src); | ||||
| 	return data; | ||||
| } | ||||
|  | ||||
| static int len (cw_Val_t * data) | ||||
| { | ||||
| 	return sizeof(data->val.byte); | ||||
| } | ||||
|  | ||||
| static void * data(cw_Val_t * data) | ||||
| { | ||||
| 	return &data->val.byte; | ||||
| } | ||||
|  | ||||
| static const char * get_type_name(cw_Val_t *data) | ||||
| { | ||||
| 	if (data->valguard != NULL){ | ||||
| 		return CW_TYPE_STR->name; | ||||
| 	} | ||||
| 	return CW_TYPE_BYTE->name; | ||||
| } | ||||
|  | ||||
| static int cast(cw_Val_t * data) | ||||
| { | ||||
| 	if (strcmp(data->type->name,CW_TYPE_BYTE->name)==0) | ||||
| 		return 1; | ||||
| 	if (strcmp(data->type->name,CW_TYPE_STR->name)==0){ | ||||
| 		char *src = data->val.ptr; | ||||
| 		CW_TYPE_BYTE->from_str(data,src); | ||||
| 		free(src); | ||||
| 		return 1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param) | ||||
| { | ||||
| 	uint8_t n,i; | ||||
| 	int l; | ||||
| 	char skey[CW_CFG_MAX_KEY_LEN]; | ||||
| 	const struct cw_ValArrayDef * def = param; | ||||
|  | ||||
| 	 | ||||
| 	const int (*fun)(cw_Cfg_t*,const char *k,const uint8_t *s,int len,const void *p,int *l) = def->get_count; | ||||
|  | ||||
| 	n = fun(cfg,key,src,len,param,&l); | ||||
|  | ||||
| 	for (i=0; i<n && l<len; i++){ | ||||
| 		sprintf(skey,"%s.%d",key,i); | ||||
| //		printf("SKEY: %s\n",skey); | ||||
| 		l+=def->type->read(cfg,skey,src,len,def->param); | ||||
| 	} | ||||
|  | ||||
| 	return l; | ||||
|  | ||||
| } | ||||
|  | ||||
| static 	int bwrite(cw_Cfg_t ** cfgs, const char *key, uint8_t *dst, const void * param) | ||||
| { | ||||
| 	int i,l; | ||||
| 	char skey[CW_CFG_MAX_KEY_LEN]; | ||||
| 	const struct cw_ValArrayDef * def = param; | ||||
| 	const int (*fun)(cw_Cfg_t**,const char *k, uint8_t *s,const void *p,int l) = def->put_count; | ||||
|  | ||||
|  | ||||
| 	i=0,l=0; | ||||
| 	do { | ||||
| 		sprintf(skey,"%s.%d",key,i); | ||||
| //		printf("iSKEY %s\n",skey); | ||||
| 		i++; | ||||
| 		if (cw_cfg_get_l(cfgs,skey,NULL)==NULL){ | ||||
| 			break; | ||||
| 		} | ||||
| 		l+=def->type->write(cfgs,skey,dst,def->param); | ||||
| 	}while(1); | ||||
|  | ||||
| //	printf("LEN: %d (K: %s)\n",l,key); | ||||
| 	fun(cfgs,key,dst,param,l); | ||||
| 	return l; | ||||
| } | ||||
|  | ||||
| const struct cw_Type cw_type_array = { | ||||
| 	"Array",			/* name */ | ||||
| 	NULL,			/* del */ | ||||
| 	put,			/* put */ | ||||
| 	get,			/* get */ | ||||
| 	to_str,			/* to_str */ | ||||
| 	from_str,		/* from_str */  | ||||
| 	len,			/* len */ | ||||
| 	data,			/* data */ | ||||
| 	get_type_name,		/* get_type_name */ | ||||
| 	cast, | ||||
| 	bread, | ||||
| 	bwrite | ||||
|  | ||||
| }; | ||||
							
								
								
									
										84
									
								
								src/cw/cw_type_bits.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/cw/cw_type_bits.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | ||||
| #include "val.h" | ||||
| #include "cfg.h" | ||||
| #include "dbg.h" | ||||
|  | ||||
| static int get_len(const struct cw_ValBit *bits) | ||||
| { | ||||
| 	int i; | ||||
| 	for (i=0;bits[i].key!=NULL;i++); | ||||
| 	return bits[i].bit;  | ||||
| } | ||||
|  | ||||
| static int get_bit(const uint8_t * src,int pos, int len) | ||||
| { | ||||
| 	int b; | ||||
| 	uint8_t m; | ||||
|        	b = len-1-pos/8; | ||||
| 	m = 1<<(pos%8); | ||||
| 	return src[b]&m ? 1:0; | ||||
| } | ||||
|  | ||||
| static void set_bit(uint8_t * dst,int pos, int len,int val) | ||||
| { | ||||
| 	int b; | ||||
| 	uint8_t m; | ||||
| 	cw_dbg(DBG_X,"set bit val %d",val); | ||||
| 	if (!val) | ||||
| 		return; | ||||
|        	b = len-1-pos/8; | ||||
| 	m = 1<<(pos%8); | ||||
| 	dst[b]|=m; | ||||
| } | ||||
|  | ||||
| static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param) | ||||
| { | ||||
| 	char skey[CW_CFG_MAX_KEY_LEN]; | ||||
| 	const struct cw_ValBit * bits=param; | ||||
| 	int l,i; | ||||
| 	 | ||||
| 	l = get_len(bits); | ||||
| 	for(i=0;bits[i].key!=NULL;i++){ | ||||
| 		sprintf(skey,"%s/%s",key,bits[i].key); | ||||
| 		cw_cfg_set_bool(cfg,skey,get_bit(src,bits[i].bit,l)); | ||||
| 	} | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| static 	int bwrite(cw_Cfg_t ** cfgs, const char *key, uint8_t *dst, const void * param) | ||||
| { | ||||
| 	int l,i; | ||||
| 	char skey[CW_CFG_MAX_KEY_LEN]; | ||||
| 	const struct cw_ValBit * bits=param; | ||||
| 	l = get_len(bits); | ||||
| 	memset(dst,0,l); | ||||
| 	for(i=0;bits[i].key!=NULL;i++){ | ||||
| 		uint8_t val; | ||||
| 		int rc; | ||||
| 		val=0; | ||||
| 		sprintf(skey,"%s/%s",key,bits[i].key); | ||||
| 		rc = CW_TYPE_BOOL->write(cfgs, skey, &val, NULL); | ||||
| 		if (rc<0) | ||||
| 			val=0; | ||||
| 		cw_dbg(DBG_X,"%s (rc: %d)",skey,rc); | ||||
| 		set_bit(dst,bits[i].bit,l,val); | ||||
| 	} | ||||
| 	return l; | ||||
| } | ||||
|  | ||||
|  | ||||
| const struct cw_Type cw_type_bits = { | ||||
| 	"Bits",			/* name */ | ||||
| 	NULL,			/* del */ | ||||
| 	NULL,			/* put */ | ||||
| 	NULL,			/* get */ | ||||
| 	NULL,			/* to_str */ | ||||
| 	NULL,		/* from_str */  | ||||
| 	NULL,			/* len */ | ||||
| 	NULL,			/* data */ | ||||
| 	NULL,		/* get_type_name */ | ||||
| 	NULL, | ||||
| 	bread, | ||||
| 	bwrite | ||||
|  | ||||
| }; | ||||
| @ -38,14 +38,12 @@ static int read_struct(cw_Cfg_t * cfg,const cw_ValStruct_t * stru, const char *p | ||||
| 			default: | ||||
| 				l = stru[i].len; | ||||
| 				if (pos+l > len){ | ||||
| 					l = len-pos; | ||||
| 					l = pos<len ? len-pos : 0 ; | ||||
| 				} | ||||
| 			 | ||||
| 		} | ||||
|  | ||||
| 		l=stru[i].type->read(cfg,key,data+pos,l,stru[i].valguard); | ||||
|  | ||||
| 		 | ||||
| //		printf("READ STRUCT (%d): %s: %s\n",pos,key,dbstr); | ||||
| 		 | ||||
| 		if (stru[i].len==-1){ | ||||
| @ -81,6 +79,7 @@ static int write_struct(cw_Cfg_t ** cfgs,  const cw_ValStruct_t * stru, const ch | ||||
| 	int pos, i; | ||||
| 	const char * result; | ||||
| 	int wrlen; | ||||
| 	int rc; | ||||
|  | ||||
| 	cw_Val_t val; | ||||
| 	memset(&val,0,sizeof(cw_Val_t)); | ||||
| @ -100,7 +99,10 @@ static int write_struct(cw_Cfg_t ** cfgs,  const cw_ValStruct_t * stru, const ch | ||||
| 		else	 | ||||
| 			sprintf(key,"%s",pkey); | ||||
|  | ||||
| 		result = cw_cfg_get_l(cfgs,key,NULL); | ||||
| 	//	result = cw_cfg_get_l(cfgs,key,NULL); | ||||
| 	 | ||||
| 		rc = cw_cfg_base_exists_l(cfgs,key); | ||||
| //		cw_dbg(DBG_X,"Base? :'%s', %d\n",key,rc); | ||||
| 		if(result) { | ||||
| //			char s[2048]; | ||||
| //			result->type->to_str(result,s,2048); | ||||
| @ -108,9 +110,15 @@ static int write_struct(cw_Cfg_t ** cfgs,  const cw_ValStruct_t * stru, const ch | ||||
| 		}	 | ||||
|  | ||||
| 		 | ||||
| 		if (result == NULL){ | ||||
| 			cw_log(LOG_ERR,"Can't put %s, no value found, filling wth zeros.",key); | ||||
| 			memset(dst+pos,0,stru[i].len); | ||||
| 		if (!rc){ | ||||
| 			int l; | ||||
| 			cw_log(LOG_ERR,"Can't put %s, no value found, filling with zeros.",key); | ||||
| 			l = stru[i].len; | ||||
| 			if (l==-1) | ||||
| 				l = 0; | ||||
|  | ||||
| 			memset(dst+pos,0,l); | ||||
| 			wrlen=l; | ||||
| 		} | ||||
| 		else{ | ||||
| 			struct cw_Type * type; | ||||
|  | ||||
| @ -8,55 +8,38 @@ | ||||
| int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list, | ||||
|                                  int subelem_id, const char * parent_key ) | ||||
| { | ||||
| 	char key[256]; | ||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | ||||
| 	uint32_t vendor; | ||||
| 	//bstr16_t version; | ||||
| 	bstr16_t version; | ||||
| 	const char *vendor_s; | ||||
|  | ||||
| 	uint8_t *d; | ||||
|  | ||||
|  | ||||
| 	/*        d += cw_put_dword(d, bstrv_get_vendor_id(v)); | ||||
| 	d += cw_put_dword(d, (subelem_id << 16) | bstrv_len(v)); | ||||
| 	d += cw_put_data(d, bstrv_data(v), bstrv_len(v)); | ||||
| 	*/ | ||||
| 	sprintf (key, "%s/%s", parent_key, CW_SKEY_VENDOR); | ||||
| 	vendor_s = cw_cfg_get_l (cfg_list, key, NULL); | ||||
| 	 | ||||
| 	if (vendor_s == NULL) { | ||||
| 		cw_log (LOG_ERR, "Can't put subelem %s, no value of type Dword found.", key); | ||||
| 		return 0; | ||||
| 		cw_log (LOG_ERR, "Can't put subelem %s, no value found. Setting zero.", key); | ||||
| 		vendor_s = "0"; | ||||
| 	} | ||||
|  | ||||
| 	vendor = atoi(vendor_s);	 | ||||
|  | ||||
|  | ||||
|  | ||||
| 	sprintf (key, "%s/%s", parent_key, CW_SKEY_VERSION); | ||||
| 	cw_Val_t * val = cw_cfg_get_val_l(cfg_list, key, CW_TYPE_BSTR16); | ||||
|  | ||||
| 	//version = cw_cfg_get_bstr16 (cfg, key, NULL); | ||||
|  | ||||
|  | ||||
| 	if (val == NULL) { | ||||
| 		cw_log (LOG_ERR, "Can't put subelem %s, no value of type Bstr16 found.", key); | ||||
| 		return 0; | ||||
| 	version = cw_cfg_get_bstr16_l(cfg_list,key,NULL); | ||||
| 	if (version == NULL) { | ||||
| 		cw_log (LOG_ERR, "Can't put subelem %s, no value found. Setting zero.", key); | ||||
| 		version = bstr16_create_from_str("0.0.0.0"); | ||||
| 	} | ||||
| 	 | ||||
| 	d = dst; | ||||
| 	 | ||||
| 	/* put vendor */ | ||||
| 	d += cw_put_dword(d, vendor); //->type->put (vendor, d); | ||||
| 	d += cw_put_dword(d, vendor);  | ||||
| 	 | ||||
| 	/* put version */ | ||||
| 	 | ||||
| 	d += cw_put_dword (d, (subelem_id << 16) | val->type->len(val)); | ||||
| //	d += cw_put_bstr16(d, version); | ||||
| 	d += val->type->put(val,d); | ||||
| 	d += cw_put_dword (d, (subelem_id << 16) | bstr16_len(version)); | ||||
| 	d += cw_put_bstr16(d, version); | ||||
|  | ||||
| 	cw_val_destroy(val); | ||||
|  | ||||
| //	free(version); | ||||
| 	free(version); | ||||
| 	 | ||||
| 	return d-dst; | ||||
| } | ||||
|  | ||||
							
								
								
									
										320
									
								
								src/cw/dbg.c
									
									
									
									
									
								
							
							
						
						
									
										320
									
								
								src/cw/dbg.c
									
									
									
									
									
								
							| @ -31,6 +31,7 @@ | ||||
| #include "format.h" | ||||
| #include "ansi_colors.h" | ||||
|  | ||||
| #include "dot11.h" | ||||
|  | ||||
| /** | ||||
|  *@addtogroup DBG | ||||
| @ -47,7 +48,114 @@ uint32_t cw_dbg_opt_display = DBG_DISP_COLORS; | ||||
| /** | ||||
|  * Current debug level | ||||
|  */ | ||||
| uint32_t cw_dbg_opt_level = 0; | ||||
| //static uint32_t cw_dbg_opt_level = 0; | ||||
| // | ||||
| static struct mavl * cw_dbg_opt_level = NULL; | ||||
| static int dbg_cmp(const void *a, const void*b) | ||||
| { | ||||
| 	return (*((int*)a)-*((int*)b)); | ||||
| } | ||||
|  | ||||
|  | ||||
| struct cw_DbgStr { | ||||
| 	int level; | ||||
| 	const char *str; | ||||
| 	const char ** str_list; | ||||
| 	const char *descr; | ||||
| }; | ||||
|  | ||||
|  | ||||
| static const char * dbg_level_msg[] = { | ||||
| 	"msg_in", "msg_out", NULL | ||||
| }; | ||||
|  | ||||
| static const char * dbg_level_pkt[] = { | ||||
| 	"pkt_in", "pkt_out",  NULL | ||||
| }; | ||||
|  | ||||
| static const char * dbg_level_elem[]={ | ||||
| 	"elem_in","elem_out",NULL | ||||
| }; | ||||
|  | ||||
| static const char * dbg_level_elem_detail[] = { | ||||
| 	"elem_detail_in", "elem_detail_out", NULL | ||||
| }; | ||||
| 	 | ||||
| static const char * dbg_level_elem_all[] = { | ||||
| 	"elem", "elem_dmp", "elem_detail",NULL | ||||
| }; | ||||
|  | ||||
| static const char * dbg_level_std[] = { | ||||
| 	"msg","elem","msg_err", "elem_err", "pkt_err", "rfc", "warn", "state", "info", NULL | ||||
| /*		 | ||||
| 	DBG_MSG_IN, DBG_MSG_OUT, | ||||
| 	DBG_ELEM_IN, DBG_ELEM_OUT, | ||||
| 	DBG_MSG_ERR, DBG_ELEM_ERR, | ||||
| 	DBG_PKT_ERR, DBG_RFC, DBG_WARN, | ||||
| 	DBG_STATE, DBG_INFO, | ||||
| 	0*/ | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Debug strings | ||||
|  */ | ||||
| struct cw_DbgStr cw_dbg_strings[] = { | ||||
| 	{ 0, 			"std", dbg_level_std, "some useful standard options to debug CAPWAP"}, | ||||
| 	{ 0,			"msg", dbg_level_msg, "messages headers" }, | ||||
| 	{ 0,			"pkt", dbg_level_pkt, "packet headers" }, | ||||
| 	{ 0,			"elem", dbg_level_elem, "message elemenst" }, | ||||
| 	{ 0, 			"elem_detail", dbg_level_elem_detail, "details for message elements"}, | ||||
| 	{ 0, 			"elem_all", dbg_level_elem_all,"all possible elem options"}, | ||||
|  | ||||
| 	{ DBG_WARN,		"warn", NULL, "warnings" }, | ||||
|  | ||||
| 	{ DBG_ELEM_ERR, 	"elem_err", NULL, "errors in elements" }, | ||||
| 	{ DBG_PKT_ERR,		"pkt_err", NULL, "packets with errors which are usually would be discard" }, | ||||
| 	{ DBG_MSG_ERR,		"msg_err", NULL, "message errors"}, | ||||
| 	{ DBG_RFC,		"rfc", NULL, "errors related to RFC5415/RFC5416 viloations" }, | ||||
| 	{ DBG_CFG_UPDATES, 	"cfg_updates",NULL, "show configuration aupdates" }, | ||||
| 	{ DBG_MOD,		"mod",NULL, "module related"}, | ||||
| 	{ DBG_MOD_DETAIL,	"mod_detail",NULL, "module related details"}, | ||||
| 	{ DBG_STATE,		"state",NULL, "CAWPAP states" }, | ||||
| 	{ DBG_MSG_COMPOSE,	"msg_compose",NULL,"message composing details" }, | ||||
|  | ||||
|  | ||||
| 	{ DBG_INFO,		"info", NULL, "several infos are displayed" }, | ||||
| 	{ DBG_PKT_IN,		"pkt_in",NULL, "headers of incomming packets."  }, | ||||
| 	{ DBG_PKT_OUT,		"pkt_out",NULL, "headers out outgoing packets." }, | ||||
| 	{ DBG_PKT_DMP_IN,	"pkt_dmp_in",NULL, "hex-dump incomming packets" }, | ||||
| 	{ DBG_PKT_DMP_OUT,	"pkt_dmp_out",NULL, "hex-dump outgoing packets"  }, | ||||
|  | ||||
| 	{ DBG_MSG_IN,		"msg_in", NULL, "incomming messages" }, | ||||
| 	{ DBG_MSG_OUT,		"msg_out", NULL, "outgoing messages" }, | ||||
| 	{ DBG_MSG_DMP_IN,	"msg_dmp_in", NULL, "hex-dump incomming messages" }, | ||||
| 	{ DBG_MSG_DMP_OUT,	"msg_dmp_out", NULL,"hex-dump of outgong messages"  }, | ||||
| 	 | ||||
|  | ||||
| 	{ DBG_ELEM_IN,  	"elem_in", NULL, "elements of incomming messages"}, | ||||
| 	{ DBG_ELEM_OUT, 	"elem_out", NULL, "elements of outgoing messages"}, | ||||
| 	{ DBG_ELEM_DETAIL_IN, 	"elem_detail_in", NULL, "details of incomming message elements" }, | ||||
| 	{ DBG_ELEM_DETAIL_OUT, 	"elem_detail_out",NULL, "details of outgoing message elememnts" }, | ||||
| 	{ DBG_ELEM_DMP, 	"elem_dmp", NULL, "hex-dump of each message element"}, | ||||
| 	{ DBG_ELEM_VNDR,	"elem_vndr", NULL, "expand vendor specific payloads"},	 | ||||
| 	 | ||||
| 	{ DBG_DTLS, 		"dtls",NULL, "DTLS related stuff"}, | ||||
| 	{ DBG_DTLS_BIO,		"dtls_bio",NULL, "DTLS BIO releated" }, | ||||
| 	{ DBG_DTLS_BIO_DMP,	"dtls_bio_dmp",NULL, "hex-dump dtls packets" }, | ||||
| 	{ DBG_DTLS_DETAIL, 	"dtls_detail",NULL, "DTLS detailed messages"}, | ||||
|  | ||||
| 	{ DBG_X,		"x", NULL, "only for developers" }, | ||||
|  | ||||
| 	{ DBG_ALL, 		"all", NULL, "all debug levels at once"}, | ||||
|  | ||||
| 	 | ||||
| 	{ 0, NULL }  | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  *@} | ||||
|  */ | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -90,7 +198,8 @@ static struct cw_StrListElem theme0[] = { | ||||
| 	{DBG_RFC, ANSI_BRED}, | ||||
| 	{DBG_X, "\x1b[31m"}, | ||||
| 	{DBG_WARN, ANSI_CYAN}, | ||||
| 	{DBG_MOD, ANSI_WHITE}, | ||||
| 	{DBG_MOD_DETAIL, ANSI_WHITE}, | ||||
| 	{DBG_MOD, ANSI_BBLACK ANSI_BOLD }, | ||||
| //	{DBG_CFG_DMP, ANSI_BCYAN },  | ||||
| 	{DBG_CFG_UPDATES,ANSI_GREEN},	 | ||||
|  | ||||
| @ -117,23 +226,24 @@ static struct cw_StrListElem color_off[] = { | ||||
| */ | ||||
|  | ||||
| static struct cw_StrListElem prefix[] = { | ||||
| 	{DBG_INFO, 		"Info -"}, | ||||
| 	{DBG_PKT_IN, 		"Pkt In  -"}, | ||||
| 	{DBG_PKT_OUT, 		"Pkt Out -"}, | ||||
| 	{DBG_INFO, 		"Info - "}, | ||||
| 	{DBG_PKT_IN, 		"Pkt In  - "}, | ||||
| 	{DBG_PKT_OUT, 		"Pkt Out - "}, | ||||
| 	{DBG_MSG_IN, 		"Msg In  - "}, | ||||
| 	{DBG_MSG_OUT,		"Msg Out - "}, | ||||
|  | ||||
| 	{DBG_ELEM_IN, 		"  Msg Element -"}, | ||||
| 	{DBG_ELEM_OUT,		"  Msg Element -"}, | ||||
| 	{DBG_ELEM_IN, 		"  Msg Element - "}, | ||||
| 	{DBG_ELEM_OUT,		"  Msg Element - "}, | ||||
| 	 | ||||
| 	{DBG_MSG_ERR, 		"  Msg Error -"}, | ||||
| 	{DBG_PKT_ERR, 		"  Pkt Error -"}, | ||||
| 	{DBG_ELEM_ERR, 		"  Elem Error -"}, | ||||
| 	{DBG_RFC, 		"  RFC -"}, | ||||
| 	{DBG_MSG_ERR, 		"  Msg Error - "}, | ||||
| 	{DBG_PKT_ERR, 		"  Pkt Error - "}, | ||||
| 	{DBG_ELEM_ERR, 		"  Elem Error - "}, | ||||
| 	{DBG_RFC, 		"  RFC - "}, | ||||
| 	{DBG_DTLS, 		"DTLS - "}, | ||||
| 	{DBG_DTLS_DETAIL,	 "DTLS - "}, | ||||
| 	{DBG_WARN,	 	"  Warning - "}, | ||||
| 	{DBG_WARN,	 	"Warning - "}, | ||||
| 	{DBG_MOD, 		"Mod - "}, | ||||
| 	{DBG_MOD_DETAIL,	"Mod - "}, | ||||
| 	{DBG_STATE, 		"STATEMACHINE - "}, | ||||
| 	{DBG_CFG_UPDATES,	"Cfg - "}, | ||||
|  | ||||
| @ -183,13 +293,19 @@ const char *get_dbg_color_ontext(int level) | ||||
|  | ||||
| int cw_dbg_is_level(int level) | ||||
| { | ||||
| 	if (level > 1 && (level &1)) | ||||
| 	if (cw_dbg_opt_level == NULL) | ||||
| 		return 0; | ||||
|  | ||||
| 	return mavl_get(cw_dbg_opt_level,&level) == NULL ? 0:1; | ||||
|  | ||||
|  | ||||
| //	if (level > 1 && (level &1)) | ||||
| 		return 1; | ||||
|  | ||||
| /*	if (level >= DBG_ALL ){ | ||||
| 		return 1; | ||||
| 	}*/ | ||||
| 	return (cw_dbg_opt_level & (level)); | ||||
| //	return (cw_dbg_opt_level & (level)); | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -256,16 +372,26 @@ void cw_dbg_pkt(int level, struct cw_Conn *conn, uint8_t * packet, int len, | ||||
| 		struct sockaddr *from) | ||||
| { | ||||
|  | ||||
| /*	int hlen;*/ | ||||
| 	char buf[1024]; | ||||
| 	int (*fmt_pkt_hdr)(char *dst, int incomming, uint8_t * packet, int len, | ||||
| 		      struct sockaddr *from); | ||||
| 	fmt_pkt_hdr = NULL; | ||||
| 	if (conn){ | ||||
| 		if (conn->msgset) | ||||
| 			fmt_pkt_hdr = conn->msgset->format_pkt_hdr; | ||||
| 	} | ||||
| 	if (fmt_pkt_hdr==NULL){ | ||||
| 		fmt_pkt_hdr = cw_format_pkt_hdr; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	if (!cw_dbg_is_level(level)) | ||||
| 		return; | ||||
| 	 | ||||
| 	if (level == DBG_PKT_IN) | ||||
| 		cw_format_pkt_hdr(buf, 1,  packet, len, from); | ||||
| 		fmt_pkt_hdr(buf, 1,  packet, len, from); | ||||
| 	else | ||||
| 		cw_format_pkt_hdr(buf, 0,  packet, len, from); | ||||
| 		fmt_pkt_hdr(buf, 0,  packet, len, from); | ||||
| 		 | ||||
| /*	hlen = cw_get_hdr_msg_offset(packet);*/ | ||||
|  | ||||
| @ -426,34 +552,166 @@ void cw_dbg_elem(int level, struct cw_Conn *conn, int msg, | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|   * Set debug level | ||||
|   * @param level debug level to set, allowed values are enumberated in #cw_dbg_levels structure. | ||||
|   * @param on 1: turns the specified debug level on, 0: turns the specified debug level off. | ||||
|   */ | ||||
|  | ||||
| void cw_dbg_set_level (int level, int on) | ||||
| { | ||||
| 	int exists; | ||||
|  | ||||
| 	if (cw_dbg_opt_level == NULL){ | ||||
| 		cw_dbg_opt_level = mavl_create(dbg_cmp,NULL,sizeof(int)); | ||||
| 		if (cw_dbg_opt_level == NULL) | ||||
| 			return; | ||||
| 	} | ||||
|  | ||||
| 	if (on){ | ||||
| 		mavl_insert(cw_dbg_opt_level,&level,&exists); | ||||
| 	} | ||||
| 	else  | ||||
| 		mavl_del(cw_dbg_opt_level,&level); | ||||
|  | ||||
|  | ||||
| /* | ||||
| void dbg_istore_dmp(mbag_t s) | ||||
| 	switch (level) { | ||||
| 		case DBG_ALL: | ||||
| 			if (on) | ||||
| 				cw_dbg_opt_level = 0xffffffff; | ||||
| 			else | ||||
| 				cw_dbg_opt_level = 0; | ||||
| 			break; | ||||
| 		default: | ||||
| 			if (on) | ||||
| 				cw_dbg_opt_level |= (level); | ||||
| 			else  | ||||
| 				cw_dbg_opt_level &= (0xffffffff) ^ (level); | ||||
| 	} | ||||
| 	*/ | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_dbg_set_level_from_str0(const char *level,int on) | ||||
| { | ||||
| 	DEFINE_AVLITER(it,s); | ||||
| 	avliter_foreach(&it) { | ||||
| 	int i,all; | ||||
| 	all = strcmp(level,"all")==0 ? 1: 0; | ||||
| 	 | ||||
| 	for(i=0; cw_dbg_strings[i].str != NULL; i++){ | ||||
| 		if (strcmp(cw_dbg_strings[i].str,level)==0 || all){ | ||||
| 			if (cw_dbg_strings[i].str_list==NULL) | ||||
| 				cw_dbg_set_level(cw_dbg_strings[i].level,on); | ||||
| 			else { | ||||
| 				const char **l; | ||||
| 				for (l=cw_dbg_strings[i].str_list; *l; l++){ | ||||
| 					if (!cw_dbg_set_level_from_str0(*l,on)){ | ||||
| 						stop(); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if (!all) | ||||
| 				return 1; | ||||
| 		} | ||||
| 	}	 | ||||
| 	if (all) | ||||
| 		return 1; | ||||
| /*	blevel = cw_strlist_get_id(cw_dbg_strings, slevel); | ||||
| 	if (blevel==-1) | ||||
| 		return 0; | ||||
| */		 | ||||
| //	cw_dbg_set_level(blevel,on); | ||||
| //	return 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| 		mbag_item_t *i = avliter_get(&it); | ||||
|  | ||||
| 		char buffer[1000]; | ||||
| int cw_dbg_set_level_from_str(const char *level) | ||||
| { | ||||
| 	int on; | ||||
| 	const char *slevel; | ||||
| 	 | ||||
| 	switch(*level){ | ||||
| 		case '-': | ||||
| 		case '!': | ||||
| 		case '~': | ||||
| 			on =0; | ||||
| 			slevel=level+1; | ||||
| 			break; | ||||
| 		case '+': | ||||
| 			slevel=level+1; | ||||
| 			on=1; | ||||
| 			break; | ||||
| 		default: | ||||
| 			slevel=level; | ||||
| 			on=1; | ||||
| 	} | ||||
| 	return cw_dbg_set_level_from_str0(slevel,on); | ||||
| } | ||||
|  | ||||
| 		struct cw_str * strings = cw_item_strings; | ||||
| 		 | ||||
| 		const char * in = cw_strlist_get_str(strings,i->id); | ||||
| 		 | ||||
| 		cw_format_item(buffer,i); | ||||
| 		printf("Item ID %d-%s: %s\n",i->id,in,buffer); | ||||
| 				 | ||||
|  | ||||
|  | ||||
|  | ||||
| void cw_dbg_print_help(FILE *out, const char * prefix) | ||||
| { | ||||
| 	struct cw_DbgStr *s; | ||||
| 	for (s=cw_dbg_strings; s->str != NULL; s++){ | ||||
| 		const char * descr = s->descr!=NULL ? s->descr : ""; | ||||
| 		fprintf(out,"%s%s: %s",prefix,s->str,descr); | ||||
| 		if (s->str_list != NULL){ | ||||
| 			const char **l; | ||||
| 			char *sp=""; | ||||
| 			fprintf(out," ("); | ||||
| 			for(l = s->str_list; *l!=NULL; l++){ | ||||
| 				fprintf(out,"%s%s",sp,*l); | ||||
| 				sp=" "; | ||||
| 			} | ||||
| 			fprintf(out,")"); | ||||
| 		} | ||||
| 		fprintf(out,"\n"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void cw_dbg_dot11_elems(const uint8_t *src,int len) | ||||
| { | ||||
| 	uint8_t id,l; | ||||
| 	int p; | ||||
| 	char str[1024]; | ||||
| 	 | ||||
| 	for(p=0; p<len; p+=l+2){ | ||||
| 		if (len-p<3){ | ||||
| 			cw_dbg(DBG_X,"Error in dot11 element"); | ||||
| 			return; | ||||
| 		} | ||||
| 		id=src[p]; | ||||
| 		l=src[p+1]; | ||||
| 		cw_format_dot11_elem(str,id,src+p+2,l); | ||||
| 		cw_dbg_dmp(DBG_X,src+p+2,l,""); | ||||
| 		cw_dbg(DBG_X,str); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| } | ||||
| */ | ||||
|  | ||||
| void cw_dbg_dot11_frame(uint8_t * frame,int len) | ||||
| { | ||||
| 	char hdr[1024]; | ||||
| 	cw_format_dot11_hdr(hdr, frame, len); | ||||
| 	cw_dbg(DBG_X,"%s",hdr); | ||||
|  | ||||
| 	int type =dot11_get_type_and_subtype(frame); | ||||
|  | ||||
| 	switch (type){ | ||||
| 		case DOT11_ASSOC_REQ: | ||||
| 			cw_dbg_dot11_elems(frame+28,len-28); | ||||
| 			break; | ||||
| 		case DOT11_ASSOC_RESP: | ||||
| 			cw_dbg_dot11_elems((frame),len-6); | ||||
| 			break; | ||||
| 			 | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| /**@}*/ | ||||
|  | ||||
							
								
								
									
										79
									
								
								src/cw/dbg.h
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								src/cw/dbg.h
									
									
									
									
									
								
							| @ -48,88 +48,91 @@ | ||||
|  */  | ||||
| enum cw_dbg_levels{ | ||||
| 	/** Show headers of incomming/outgoing CAPWAP packets */ | ||||
| 	DBG_PKT_IN 	= (1<<0),  | ||||
| 	DBG_PKT_OUT 	= (1<<1),	 | ||||
| 	DBG_PKT_IN 	= 1,  | ||||
| 	DBG_PKT_OUT,	 | ||||
|  | ||||
| 	/** Hex-dump incomming/outgoing CAPWAP packets */ | ||||
| 	DBG_PKT_DMP_IN	= (1<<3), | ||||
| 	DBG_PKT_DMP_OUT = (1<<4), | ||||
| 	DBG_PKT_DMP_IN, | ||||
| 	DBG_PKT_DMP_OUT, | ||||
|  | ||||
| 	/** Incomming CAPWAP packets with errors, wich would | ||||
| 	    usually silently discarded */  | ||||
| 	DBG_PKT_ERR	= (1<<5), | ||||
| 	DBG_PKT_ERR, | ||||
| 	 | ||||
|  | ||||
| 	/** Display incomming/outgoing CAPWAP/LWAPP messages */ | ||||
| 	DBG_MSG_IN	= (1<<6), | ||||
| 	DBG_MSG_OUT	= (1<<7), | ||||
| 	DBG_MSG_IN, | ||||
| 	DBG_MSG_OUT, | ||||
|  | ||||
| 	/** Show hex-dump of messages */ | ||||
| 	DBG_MSG_DMP_IN	= (1<<8), | ||||
| 	DBG_MSG_DMP_OUT	= (1<<9), | ||||
| 	DBG_MSG_DMP_IN, | ||||
| 	DBG_MSG_DMP_OUT, | ||||
|  | ||||
| 	/** Message errors */ | ||||
| 	DBG_MSG_ERR	= (1<<10), | ||||
| 	DBG_MSG_ERR, | ||||
|  | ||||
| 	/** Show message elements in incomming/outgoing messages */ | ||||
| 	DBG_ELEM_IN	= (1<<11), | ||||
| 	DBG_ELEM_OUT	= (1<<12), | ||||
| 	DBG_ELEM_IN, | ||||
| 	DBG_ELEM_OUT, | ||||
|  | ||||
| 	/** Show message element details  */ | ||||
| 	DBG_ELEM_DETAIL_IN = (1<<13), | ||||
| 	DBG_ELEM_DETAIL_OUT = (1<<14), | ||||
| 	DBG_ELEM_DETAIL_IN, | ||||
| 	DBG_ELEM_DETAIL_OUT, | ||||
|  | ||||
| 	/** Error in msg elements */ | ||||
| 	DBG_ELEM_ERR	= (1<<15), | ||||
| 	DBG_ELEM_ERR, | ||||
|  | ||||
| 	/** hex dump elements */	 | ||||
| 	DBG_ELEM_DMP	= (1<<16), | ||||
| 	DBG_ELEM_DMP, | ||||
|  | ||||
| 	/** General infos, like CAPWAP state */ | ||||
| 	DBG_INFO	= (1<<17),	 | ||||
| 	DBG_INFO,	 | ||||
|  | ||||
| 	/** Misc. warnings */ | ||||
| 	DBG_WARN	= (1<<18), | ||||
| 	DBG_WARN, | ||||
|  | ||||
| 	/** RFC related */ | ||||
| 	DBG_RFC		= (1<<19), | ||||
| 	DBG_RFC, | ||||
|  | ||||
| 	/** DTLS related messages */ | ||||
| 	DBG_DTLS	= (1<<20), | ||||
| 	DBG_DTLS, | ||||
|  | ||||
| 	/** DTLS BIOs in/out */ | ||||
| 	DBG_DTLS_BIO	= (1<<21), | ||||
| 	DBG_DTLS_BIO, | ||||
|  | ||||
| 	/** Dump DTLS BIO i/o */ | ||||
| 	DBG_DTLS_BIO_DMP = (1<<22), | ||||
| 	DBG_DTLS_BIO_DMP, | ||||
|  | ||||
| 	/** Show DTLS Details */ | ||||
| 	DBG_DTLS_DETAIL	= (1<<23), | ||||
| 	DBG_DTLS_DETAIL, | ||||
| 	 | ||||
| //	DBG_CFG_DMP	= (1<<20), | ||||
| //	DBG_CFG_DMP, | ||||
|  | ||||
| //	DBG_CFG_SET	= (1<<21), | ||||
| //	DBG_CFG_SET, | ||||
|  | ||||
| 	/** Debug Mods */ | ||||
| 	DBG_MOD		= (1<<24), | ||||
| 	DBG_MOD, | ||||
| 	 | ||||
|        	/**Debug State machine */ | ||||
| 	DBG_STATE	= (1<<25), | ||||
| 	DBG_STATE, | ||||
| 	 | ||||
| 	 | ||||
| 	DBG_MSG_COMPOSE	= (1<<26), | ||||
| 	DBG_MSG_COMPOSE, | ||||
|  | ||||
| 	DBG_CFG_UPDATES	= (1<<27), | ||||
| 	DBG_CFG_UPDATES, | ||||
|  | ||||
| 	DBG_ELEM_VNDR	= (1<<28), | ||||
| 	DBG_ELEM_VNDR, | ||||
| 	 | ||||
|  | ||||
| 	DBG_X		= (1<<30), | ||||
| 	DBG_ALL 	= (0x7fffffff), | ||||
| 	DBG_X, | ||||
|  | ||||
| 	DBG_MOD_DETAIL, | ||||
|  | ||||
| 	DBG_ALL, | ||||
|  | ||||
|  | ||||
| 	DBG_ELEM_DMP_IN	= 7, | ||||
| 	DBG_ELEM_DMP_OUT = 9, | ||||
| 	DBG_ELEM_DMP_IN, | ||||
| 	DBG_ELEM_DMP_OUT, | ||||
|  | ||||
|  | ||||
| }; | ||||
| @ -189,8 +192,8 @@ void cw_dbg_dmp(int level, const uint8_t * data, int len, const char *format, .. | ||||
|  | ||||
|  | ||||
| extern uint32_t cw_dbg_opt_display; | ||||
| extern uint32_t cw_dbg_opt_level; | ||||
| extern struct cw_StrListElem cw_dbg_strings[]; | ||||
| //extern uint32_t cw_dbg_opt_level; | ||||
| //extern struct cw_StrListElem cw_dbg_strings[]; | ||||
|  | ||||
| /* | ||||
| #define cw_dbg cw_dbg_colored | ||||
| @ -240,6 +243,10 @@ void cw_dbg_ktv_dump(mavl_t ktv, uint32_t dbglevel, | ||||
| */ | ||||
| int cw_dbg_is_level(int level); | ||||
|  | ||||
| void cw_dbg_print_help(FILE *out, const char * prefix); | ||||
| void cw_dbg_dot11_frame(uint8_t * frame,int len); | ||||
|  | ||||
|  | ||||
|  | ||||
| #define stop() printf("STOP IN %s:%d - %s\n", __FILE__, __LINE__, __FUNCTION__); exit(1) | ||||
|  | ||||
|  | ||||
| @ -65,6 +65,7 @@ struct cw_StrListElem cw_dbg_strings[] = { | ||||
| 	{ DBG_DTLS_DETAIL, 	"dtls_detail"}, | ||||
|  | ||||
| 	{ DBG_CFG_UPDATES, 	"cfg_updates" }, | ||||
| 	{ DBG_X,		"x" }, | ||||
|  | ||||
| 	 | ||||
| //	{DBG_CFG_DMP, "cfg_dmp" }, | ||||
| @ -85,9 +86,7 @@ struct cw_StrListElem cw_dbg_strings[] = { | ||||
| 		DBG_ELEM_IN | DBG_ELEM_OUT | | ||||
| 		DBG_MSG_ERR | DBG_ELEM_ERR | | ||||
| 		DBG_PKT_ERR | DBG_RFC | DBG_WARN | ||||
|  | ||||
|  | ||||
| 		| DBG_STATE), 			"std" }, | ||||
| 		| DBG_STATE | DBG_INFO), 			"std" }, | ||||
|  | ||||
| 	{ DBG_ALL, 		"all"}, | ||||
|  | ||||
| @ -121,7 +120,7 @@ struct cw_dbg_cfgstrs cw_dbg_cfgstrs[] = { | ||||
| 	{"elem_err",DBG_ELEM_ERR}, | ||||
|  | ||||
| 	{"dtls",DBG_DTLS}, | ||||
| 	{"dtls_dietail",DBG_DTLS_DETAIL}, | ||||
| 	{"dtls_detail",DBG_DTLS_DETAIL}, | ||||
| 	{"dtls_bio",DBG_DTLS_BIO}, | ||||
| 	{"dtls_bio_dmp",DBG_DTLS_BIO_DMP}, | ||||
|  | ||||
|  | ||||
| @ -38,3 +38,28 @@ const char * dot11_type_strings[]= | ||||
| 	"Probe Req", | ||||
| 	"Probe Resp" | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct dot11_name{ | ||||
| 	uint8_t val; | ||||
| 	const char * str; | ||||
| }; | ||||
|  | ||||
| struct cw_StrListElem dot11_names[]={ | ||||
| 	{DOT11_ASSOC_REQ, "Assoc Req"}, | ||||
| 	{DOT11_ASSOC_RESP, "Assoc Resp"}, | ||||
| 	{DOT11_REASSOC_REQ, "Reassoc Req"}, | ||||
| 	{DOT11_REASSOC_RESP, "Reassoc Resp"}, | ||||
| 	{DOT11_PROBE_REQ, "Probe Req"},	 | ||||
| 	{DOT11_PROBE_RESP, "Probe Resp"}, | ||||
| 	{DOT11_TIMING_ADV, "Timing Adv"}, | ||||
| 	{DOT11_MGM_RES111, "MGMRES111"}, | ||||
| 	{DOT11_BEACON, "Beacon"}, | ||||
| 	{CW_STR_STOP,"Unknown"}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| int dot11_init_assoc_resp(uint8_t * dst) | ||||
| { | ||||
| 	dot11_set_type_and_subtype(dst,DOT11_ASSOC_RESP); | ||||
| } | ||||
|  | ||||
							
								
								
									
										124
									
								
								src/cw/dot11.h
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								src/cw/dot11.h
									
									
									
									
									
								
							| @ -20,6 +20,7 @@ | ||||
| #include <endian.h> | ||||
| #endif | ||||
|  | ||||
| #include "strlist.h" | ||||
|  | ||||
| /** | ||||
|  * @defgroup DOT11_FRAME_TYPES Frame Types | ||||
| @ -47,17 +48,17 @@ | ||||
|  * | ||||
|  * @{ | ||||
|  */ | ||||
| #define DOT11_FC_ASSOC_REQ	dot11_fc_mgm(0b0000) | ||||
| #define DOT11_FC_ASSOC_RESP	dot11_fc_mgm(0b0001) | ||||
| #define DOT11_FC_REASSOC_REQ	dot11_fc_mgm(0b0010) | ||||
| #define DOT11_FC_REASSOC_RESP	dot11_fc_mgm(0b0011) | ||||
| #define DOT11_FC_PROBE_REQ	dot11_fc_mgm(0b0100) | ||||
| #define DOT11_FC_PROBE_RESP	dot11_fc_mgm(0b0101) | ||||
| #define DOT11_FC_TIMING_ADV	dot11_fc_mgm(0b0110) | ||||
| #define DOT11_FC_MGM_RES111	dot11_fc_mgm(0b0111) | ||||
| #define DOT11_FC_BEACON		dot11_fc_mgm(0b1000) | ||||
| #define DOT11_ASSOC_REQ		dot11_fc_mgm(0b0000) | ||||
| #define DOT11_ASSOC_RESP	dot11_fc_mgm(0b0001) | ||||
| #define DOT11_REASSOC_REQ	dot11_fc_mgm(0b0010) | ||||
| #define DOT11_REASSOC_RESP	dot11_fc_mgm(0b0011) | ||||
| #define DOT11_PROBE_REQ		dot11_fc_mgm(0b0100) | ||||
| #define DOT11_PROBE_RESP	dot11_fc_mgm(0b0101) | ||||
| #define DOT11_TIMING_ADV	dot11_fc_mgm(0b0110) | ||||
| #define DOT11_MGM_RES111	dot11_fc_mgm(0b0111) | ||||
| #define DOT11_BEACON		dot11_fc_mgm(0b1000) | ||||
|  | ||||
| #define DOT11_FC_DATA		dot11_fc_dta(0b0000) | ||||
| #define DOT11_DATA		dot11_fc_dta(0b0000) | ||||
|  | ||||
| /** | ||||
|  * @} | ||||
| @ -109,11 +110,19 @@ | ||||
|  * @defgroup DOT11_ELEMS  | ||||
|  * @{ | ||||
|  */ | ||||
| #define DOT11_ELEM_SSID			0 | ||||
| #define DOT11_ELEM_SUPPORTED_RATES	1 | ||||
| #define DOT11_ELEM_FH_PARAM_SET		2 | ||||
| #define DOT11_ELEM_DSSS_PARAM_SET	3 | ||||
| #define DOT11_ELEM_CF_PARAM_SET		4 | ||||
| #define DOT11_ELEM_SSID				0 | ||||
| #define DOT11_ELEM_SUPPORTED_RATES		1 | ||||
| #define DOT11_ELEM_FH_PARAM_SET			2 | ||||
| #define DOT11_ELEM_DSSS_PARAM_SET		3 | ||||
| #define DOT11_ELEM_CF_PARAM_SET			4 | ||||
| #define DOT11_ELEM_POWER_CAPABILITY		33 | ||||
| #define DOT11_ELEM_SUPPORTED_CHANNELS		36 | ||||
| #define DOT11_ELEM_EXTENDED_SUPPORTED_RATES	50 | ||||
| #define DOT11_ELEM_AP_CHANNEL_REPORT		51 | ||||
| #define DOT11_ELEM_SUPPORTED_OPERATING_CLASSES	59 | ||||
| #define DOT11_ELEM_VENDOR_SPECIFIC		221 | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * @} | ||||
|  */ | ||||
| @ -125,27 +134,32 @@ extern const uint8_t dot11_tab_br[256]; | ||||
|  | ||||
| #define dot11_get_byte(ptr) (*(ptr)) | ||||
|  | ||||
| #define dot11_put_byte(ptr,b) (*(ptr) = b) | ||||
| #define dot11_put_byte(ptr,b) (*(ptr) = b,1) | ||||
| #define dot11_put_word(dst,v) ((*((uint16_t*)(dst))=htobe16(v)),2) | ||||
| #define dot11_put_dword(dst,v) ((*((uint16_t*)(dst))=htobe16(v)),4) | ||||
| #define dot11_put_dword(dst,v) ((*((uint32_t*)(dst))=htobe32(v)),4) | ||||
| #define dot11_put_qword(dst,v) ((*((uint64_t*)(dst))=htobe64(v)),8) | ||||
|  | ||||
| #define dot11_set_byte(ptr,b) (*(ptr) = b) | ||||
| #define dot11_set_word(dst,v) ((*((uint16_t*)(dst))=htobe16(v))) | ||||
| #define dot11_set_dword(dst,v) ((*((uint32_t*)(dst))=htobe32(v))) | ||||
| #define dot11_set_qword(dst,v) ((*((uint64_t*)(dst))=htobe64(v))) | ||||
|  | ||||
|  | ||||
|  | ||||
| #define dot11_set_byte(ptr,b) (*(ptr) = b) | ||||
|  | ||||
| uint16_t dot11_get_word(uint8_t * ptr); | ||||
|  | ||||
|  | ||||
|  | ||||
| #define dot11_get_version(frame) ((frame[1])&0x03) | ||||
| #define dot11_get_type(frame) (((frame[1])&0x0c) >> 2) | ||||
| #define dot11_get_subtype(frame) (((frame[1])&0xf0) >> 4) | ||||
| /**  | ||||
|  * Get Frame Control field  | ||||
|  * @param frame | ||||
|  * @return Frame Control field | ||||
|  */ | ||||
| #define dot11_get_fc(frame) dot11_get_word(frame) | ||||
| #define dot11_get_version(frame) ( (frame)[1] & 0x03) | ||||
| #define dot11_get_type(frame)    ( ((frame)[1] & 0x0c) >> 2) | ||||
| #define dot11_get_subtype(frame) ( (frame)[1] >> 4 ) | ||||
|  | ||||
| #define dot11_get_type_and_subtype(frame) ((frame)[1]) | ||||
| #define dot11_set_type_and_subtype(frame,val) ((frame)[1]=val) | ||||
|  | ||||
|  | ||||
| #define dot11_get_duration(frame) dot11_get_word(frame+2) | ||||
|  | ||||
|  | ||||
| void dot11_get_address(uint8_t * dst, uint8_t * frame); | ||||
| @ -201,6 +215,9 @@ void dot11_timer_set(uint64_t val); | ||||
| #define dot11_put_address(dst,addr) (memcpy(dst,addr,6),6) | ||||
| #define dot11_put_sequence_control(dst,v) (dot11_put_word(dst,v)) | ||||
| #define dot11_put_capability(dst,v) dot11_put_word(dst,v) | ||||
|  | ||||
|  | ||||
|  | ||||
| int  dot11_put_ssid(uint8_t *dst,uint8_t * ssid,int len); | ||||
|  | ||||
|  | ||||
| @ -235,6 +252,59 @@ extern uint8_t dot11_broadcast_address[6]; | ||||
|  | ||||
|  | ||||
|  | ||||
| extern struct cw_StrListElem dot11_names[]; | ||||
|  | ||||
| #define dot11_get_frame_name(data) cw_strlist_get_str(dot11_names,(data)[1]) | ||||
|  | ||||
| /**  | ||||
|  * Get Frame Control field  | ||||
|  * @param frame uint8_t pointer to the frame | ||||
|  * @return uint16_t Frame Control field | ||||
|  */ | ||||
| #define dot11_get_fc(frame) dot11_get_word(frame) | ||||
|  /** Get duration/aid field  | ||||
|   * @param frame uint8_t pointer to frame */ | ||||
| #define dot11_get_duration(frame) dot11_get_word(frame+2) | ||||
| #define dot11_get_da(frame) ((frame)+4) | ||||
| #define dot11_get_sa(frame) ((frame)+10) | ||||
| #define dot11_get_bssid(frame) ((frame)+16) | ||||
| #define dot11_get_seq(frame) dot11_get_word((frame)+22) | ||||
| #define dot11_get_body(frame) ((frame)+24) | ||||
|  | ||||
|  | ||||
|  | ||||
| #define dot11_set_duration(frame,d) dot11_set_word(frame+2,d) | ||||
| #define dot11_set_seq(frame,s) dot11_set_word((frame)+22,s) | ||||
|  | ||||
|  | ||||
| #define dot11_assoc_req_get_cap(frame) \ | ||||
| 		dot11_get_word((frame)+24) | ||||
| #define dot11_assoc_req_get_listen_interval(frame) \ | ||||
| 			dot11_get_word((frame)+24+2) | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
| #define dot11_assoc_req_get_ssid_len(frame)\ | ||||
| 			((frame)[29]) | ||||
| #define dot11_assoc_req_get_ssid(frame)\ | ||||
| 			(frame+30) | ||||
| */ | ||||
| #define dot11_assoc_resp_set_cap(frame,cap)\ | ||||
| 	dot11_set_word(dot11_get_body(frame),cap) | ||||
| #define dot11_assoc_resp_set_status_code(frame,code)\ | ||||
| 	dot11_set_word(dot11_get_body(frame)+2,code) | ||||
| #define dot11_assoc_resp_set_assoc_id(frame,id)\ | ||||
| 	dot11_set_word(dot11_get_body(frame)+4,id) | ||||
|  | ||||
| //#define dot11_assoce_resp_get_var_body(frame)  | ||||
| //	(get_frame_body(frame)+6) | ||||
|  | ||||
|  | ||||
|  | ||||
| #define dot11_copy_mac(src,dst)\ | ||||
| 	memcpy(dst,src,6); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -31,8 +31,6 @@ uint64_t dot11_timer_get() | ||||
| 	return 1000000 * tv.tv_sec + tv.tv_usec - dot11_timer_offset; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void dot11_timer_set(uint64_t val) | ||||
| { | ||||
| 	struct timeval tv; | ||||
| @ -41,11 +39,10 @@ void dot11_timer_set(uint64_t val) | ||||
| } | ||||
|  | ||||
| int  dot11_put_ssid(uint8_t *dst,uint8_t * ssid,int len){ | ||||
| 	dot11_put_byte(dst,DOT11_ELEM_SSID); | ||||
| 	dot11_put_byte(dst+1,len); | ||||
| 	dot11_set_byte(dst,DOT11_ELEM_SSID); | ||||
| 	dot11_set_byte(dst+1,len); | ||||
| 	memcpy(dst+2,ssid,len); | ||||
| 	return len; | ||||
|  | ||||
| } | ||||
|  | ||||
| int dot11_put_supported_rates(uint8_t *dst, float *basic, float *rates){ | ||||
| @ -67,10 +64,14 @@ int dot11_put_supported_rates(uint8_t *dst, float *basic, float *rates){ | ||||
|  | ||||
| int dot11_put_dsss_param_set(uint8_t *dst,int ch) { | ||||
|  | ||||
| 	dot11_put_byte(dst,DOT11_ELEM_DSSS_PARAM_SET); | ||||
| 	dot11_put_byte(dst+1,1); | ||||
| 	dot11_put_byte(dst+2,ch); | ||||
| 	dot11_set_byte(dst,DOT11_ELEM_DSSS_PARAM_SET); | ||||
| 	dot11_set_byte(dst+1,1); | ||||
| 	dot11_set_byte(dst+2,ch); | ||||
| 	return 3; | ||||
| } | ||||
|  | ||||
|  | ||||
| #define DOT11_INLINE  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -305,7 +305,10 @@ static unsigned int psk_server_cb(SSL *ssl,const char *identity, unsigned char * | ||||
| */ | ||||
|  | ||||
|  | ||||
|  | ||||
| static unsigned int timer_cb(SSL *s, unsigned int timer_us) | ||||
| { | ||||
| 	return 5000000; | ||||
| } | ||||
|  | ||||
| struct dtls_openssl_data * dtls_openssl_data_create(struct cw_Conn * conn, const SSL_METHOD * method, BIO_METHOD * bio) | ||||
| { | ||||
| @ -322,7 +325,7 @@ struct dtls_openssl_data * dtls_openssl_data_create(struct cw_Conn * conn, const | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	rc = SSL_CTX_get_security_level(d->ctx); | ||||
| //	rc = SSL_CTX_get_security_level(d->ctx); | ||||
|  | ||||
| 	SSL_CTX_set_security_level(d->ctx,0); | ||||
|  | ||||
| @ -338,6 +341,8 @@ struct dtls_openssl_data * dtls_openssl_data_create(struct cw_Conn * conn, const | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| 	/* set dtls psk if exists */ | ||||
| /*	if (conn->dtls_psk) | ||||
| 		SSL_CTX_set_psk_server_callback( d->ctx, psk_server_cb); | ||||
| @ -456,6 +461,7 @@ struct dtls_openssl_data * dtls_openssl_data_create(struct cw_Conn * conn, const | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	DTLS_set_timer_cb(d->ssl,timer_cb); | ||||
| 	 | ||||
| 	d->bio = BIO_new(bio); | ||||
| /*	d->bio->ptr = conn;*/ | ||||
|  | ||||
							
								
								
									
										145
									
								
								src/cw/format.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								src/cw/format.c
									
									
									
									
									
								
							| @ -27,6 +27,10 @@ | ||||
|  | ||||
| #include "cw.h" | ||||
|  | ||||
| #include "format.h" | ||||
|  | ||||
| #include "capwap80211.h" | ||||
|  | ||||
| /** | ||||
|  * Format bytes as hex string. | ||||
|  * @param dst Destination buffer | ||||
| @ -87,4 +91,145 @@ int format_hdr_flags(char *dst, uint8_t * th) | ||||
|  | ||||
| } | ||||
|  | ||||
| char * cw_format_radio_information(char * dst, int ri) | ||||
| { | ||||
| 	char *d = dst;	 | ||||
| 	if (ri & CW_80211_RADIO_TYPE_A) | ||||
| 		*d++='a'; | ||||
| 	if (ri & CW_80211_RADIO_TYPE_B) | ||||
| 		*d++='b'; | ||||
| 	if (ri & CW_80211_RADIO_TYPE_G) | ||||
| 		*d++='g'; | ||||
| 	if (ri & CW_80211_RADIO_TYPE_N) | ||||
| 		*d++='n'; | ||||
|  | ||||
| 	*d=0; | ||||
| 	return dst; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int cw_format_pkt_hdr0(char *dst, int incomming, uint8_t * packet, int len, | ||||
| 		      struct sockaddr *from, int draft7) | ||||
| { | ||||
| 	char sock_buf[SOCK_ADDR_BUFSIZE];  | ||||
| 	int preamble; | ||||
| 	char *s; | ||||
| 	int hlen, rid, wbid; | ||||
| 	int frag_id,frag_offs; | ||||
|  | ||||
| 	s = dst; | ||||
|  | ||||
| 	if (incomming){ | ||||
| 		if (cw_get_hdr_flag_f(packet)) { | ||||
| 			s += sprintf(s, "Fragment from %s", | ||||
| 				     sock_addr2str_p(from,sock_buf)); | ||||
| 		} else { | ||||
| 			s += sprintf(s, "From %s", sock_addr2str_p(from,sock_buf)); | ||||
| 		} | ||||
| 	} | ||||
| 	else{ | ||||
| 		if (cw_get_hdr_flag_f(packet)) { | ||||
| 			s += sprintf(s, "Fragment to %s", sock_addr2str(from,sock_buf)); | ||||
| 		} else { | ||||
| 			s += sprintf(s, "To %s", sock_addr2str(from,sock_buf)); | ||||
| 		} | ||||
| 	} | ||||
| 	s += sprintf(s, " l=%d: ", len); | ||||
|  | ||||
| 	preamble = cw_get_hdr_preamble(packet); | ||||
| 	if (preamble == 01) { | ||||
| 		s += sprintf(s, " (encrypted)"); | ||||
| 		return s - dst; | ||||
| 	} | ||||
|  | ||||
| 	if (len < 4) | ||||
| 		goto abort; | ||||
|  | ||||
| 	hlen = cw_get_hdr_hlen(packet); | ||||
| 	rid = cw_get_hdr_rid(packet); | ||||
| 	wbid = cw_get_hdr_wbid(packet); | ||||
| 	s += sprintf(s, " H:%d R:%02d W:%02d", hlen, rid, wbid); | ||||
|  | ||||
|  | ||||
| 	s += sprintf(s, " Flgs:"); | ||||
| 	s += format_hdr_flags(s, packet); | ||||
|  | ||||
| 	if (len < 8) | ||||
| 		goto abort; | ||||
| 	frag_id = cw_get_hdr_fragid(packet); | ||||
| 	frag_offs = cw_get_hdr_fragoffset(packet); | ||||
| 	s += sprintf(s, " Frag/Offs:%d/%d", frag_id, frag_offs); | ||||
|  | ||||
|  | ||||
| 	if (cw_get_hdr_flag_m(packet)) { | ||||
| 		/* rmac is present, print the rmac */ | ||||
| 		int rmac_len = cw_get_hdr_rmac_len(packet); | ||||
| 		int plen = rmac_len; | ||||
| 		if (rmac_len + 8 > len) | ||||
| 			plen = len - 8; | ||||
| 		if (rmac_len > 10) | ||||
| 			plen = 10; | ||||
|  | ||||
| 		s += sprintf(s, " R-MAC:"); | ||||
| 		s += format_mac(s, cw_get_hdr_rmac_data(packet), plen); | ||||
| 		if (rmac_len > 10) { | ||||
| 			s += sprintf(s, " ... (len=%d)", rmac_len); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (cw_get_hdr_flag_w(packet)) { | ||||
| 		if (!draft7){ | ||||
| 			/* print wireless specific info */ | ||||
| 			int ws_len = cw_get_hdr_ws_len(packet); | ||||
| 			int plen = ws_len > 20 ? 20 : ws_len; | ||||
| 			s += sprintf(s, " WS:"); | ||||
| 			s += format_hexu(s, cw_get_hdr_ws_data(packet), plen); | ||||
| 			if (ws_len > 20) { | ||||
| 				s += sprintf(s, " ... (len=%d)", ws_len); | ||||
| 			} | ||||
| 		} | ||||
| 		else { | ||||
| 			int ws_len = cw_get_hdr_ws_len_7(packet); | ||||
| 			int plen = ws_len > 20 ? 20 : ws_len; | ||||
| 			s += sprintf(s, " WS:"); | ||||
| 			s += format_hexu(s, cw_get_hdr_ws_data_7(packet), plen); | ||||
| 			if (ws_len > 20) { | ||||
| 				s += sprintf(s, " ... (len=%d)", ws_len); | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
| 	return s - dst; | ||||
|  | ||||
|       abort: | ||||
| 	s += sprintf(s, " Incomplete..."); | ||||
| 	return s - dst; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * @brief Format a packet header for debugging purposes | ||||
|  * @param dst Destination buffer | ||||
|  * @param incomming True if the packet is an incomming packet, otherweise 0 | ||||
|  * @param packet packet data | ||||
|  * @param len length of packet data | ||||
|  * @param from Address from where the packet was received | ||||
|  * @return Number of bytes written | ||||
|  */ | ||||
| int cw_format_pkt_hdr(char *dst, int incomming, uint8_t * packet, int len, | ||||
| 		      struct sockaddr *from) | ||||
| { | ||||
| 	return cw_format_pkt_hdr0(dst, incomming, packet, len, | ||||
| 	      from, 0); | ||||
|  | ||||
| } | ||||
|  | ||||
| int cw_format_pkt_hdr_7(char *dst, int incomming, uint8_t * packet, int len, | ||||
| 		      struct sockaddr *from) | ||||
| { | ||||
| 	return cw_format_pkt_hdr0(dst, incomming, packet, len, | ||||
| 	      from, 1); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -45,7 +45,6 @@ char *format_s_hex_bytes(char *dst, const char *format, const char *delim, | ||||
|  | ||||
| int cw_format_scan_hex_bytes(uint8_t *dst,const char *s, int len); | ||||
|  | ||||
| struct avltree; | ||||
|  | ||||
| /** | ||||
|  * Format bytes as a hex string. Hexadecimal letters are lower-case. | ||||
| @ -110,8 +109,16 @@ char *cw_format_dump(const uint8_t * data, int len, | ||||
| void cw_format_get_dump_defaults(struct cw_FormatDumpSettings * settings); | ||||
| int cw_format_pkt_hdr(char *dst, int incomming, uint8_t * packet, int len, | ||||
| 		      struct sockaddr *from); | ||||
| int cw_format_pkt_hdr_7(char *dst, int incomming, uint8_t * packet, int len, | ||||
| 		      struct sockaddr *from); | ||||
|  | ||||
| int cw_format_version(char *s, const uint8_t * version, int len); | ||||
|  | ||||
| char * cw_format_radio_information(char * dst, int ri); | ||||
| int cw_format_dot11_hdr(char * dst, uint8_t *packet, int len); | ||||
| int cw_format_dot11_elem(char *dst, uint8_t id, const uint8_t *src, int len); | ||||
|  | ||||
|  | ||||
| /**@}*/ | ||||
|  | ||||
| #endif | ||||
|  | ||||
| @ -54,6 +54,7 @@ | ||||
|  | ||||
|  | ||||
| #include "capwap.h" | ||||
| #include "cw.h" | ||||
| #include "fragman.h" | ||||
|  | ||||
| /** | ||||
| @ -101,20 +102,6 @@ static struct frag * frag_new(struct frag * frags, int fragid) | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| /* | ||||
| void fragman_free(frag_t * frags,struct frag * f) | ||||
| { | ||||
| 	int i; | ||||
| 	for (i=0; i<FRAG_MAXIDS; i++){ | ||||
| 		if (frags[i]->fragid==f->fragid){ | ||||
| 			frags[i]=NULL; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	free(f); | ||||
| } | ||||
| */ | ||||
|  | ||||
| /** | ||||
|  * Add a fragment | ||||
|  * @pram frags Fragman object | ||||
| @ -129,12 +116,10 @@ uint8_t * fragman_add(frag_t * frags, uint8_t *packet, int hlen, int payloadlen) | ||||
| 	uint32_t val0,val1; | ||||
| 	int fragid,fragoffset; | ||||
| 	int dst; | ||||
| 	int ti; | ||||
| 	 | ||||
| 	/* read the transport header dword 0, | ||||
| 	 * contains hlen*/	 | ||||
| 	val0 = ntohl(*((uint32_t*)packet)); | ||||
| /*	int hlen = (val0 >> 19) & 0x1f;*/ | ||||
|  | ||||
| 	/* read the transport header dword 1, | ||||
| 	 * contains fragid and fragoffset */	 | ||||
| @ -142,33 +127,30 @@ uint8_t * fragman_add(frag_t * frags, uint8_t *packet, int hlen, int payloadlen) | ||||
| 	fragid = val1>>16; | ||||
| 	fragoffset=(val1 >>3) & 0x1fff; | ||||
|  | ||||
| /*//	printf("Fragid = %i, offset = %i\n",fragid,fragoffset);*/ | ||||
| 	 | ||||
| 	/* determine size of payload */ | ||||
| /*	int payloadlen = len - hlen*4; | ||||
| 	if (payloadlen<0){ | ||||
| 		errno = EINVAL; | ||||
| 		return NULL; | ||||
| 	} | ||||
| */ | ||||
| 	/* find / create cfragment */ | ||||
| 	f = frag_get(frags,fragid); | ||||
| 	if (!f){ | ||||
| 		f = frag_new(frags,fragid); | ||||
| 		if (!f){ | ||||
| 			errno = ENOMEM; | ||||
| 			/* out of fragmentation space */ | ||||
| 			return NULL; | ||||
| 		} | ||||
| 	} | ||||
| 	if (!f){ | ||||
| 		errno = ENOMEM; | ||||
| 		/* out of fragmentation space */ | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	errno = 0; | ||||
|  | ||||
| 	dst = fragoffset*8; | ||||
|  | ||||
| 	/* copy fragment*/ | ||||
| 	if (dst + payloadlen < FRAG_MAXSIZE) { | ||||
| 		memcpy( f->buffer+4+dst,packet+hlen,payloadlen); | ||||
| 		if (fragoffset==0){ | ||||
| 			/* preserve header of 1st fragment */ | ||||
| 			memset(f->buffer,0,MAX_PKT_HDR_LEN); | ||||
| 			memcpy(f->buffer,packet,hlen); | ||||
| 			cw_set_hdr_hlen(f->buffer,MAX_PKT_HDR_LEN/4); | ||||
| 			cw_set_hdr_flags(f->buffer, CAPWAP_FLAG_HDR_F, 0); | ||||
| 		} | ||||
| 		memcpy( f->buffer+MAX_PKT_HDR_LEN+4+dst,packet+hlen,payloadlen); | ||||
| 		f->bytesreceived+=payloadlen; | ||||
| 	} | ||||
|  | ||||
| @ -176,22 +158,14 @@ uint8_t * fragman_add(frag_t * frags, uint8_t *packet, int hlen, int payloadlen) | ||||
| 		f->bytesneeded=dst+payloadlen; | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
| 	for (ti=0; ti<16; ti++){ | ||||
| /*//		printf("%02X ",(f->buffer+4)[ti]);*/ | ||||
|  | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	if (f->bytesneeded>0 && f->bytesneeded<=f->bytesreceived){ | ||||
| 		uint8_t * r=f->buffer; | ||||
| 		f->buffer=0; | ||||
| /*//		printf("last bytes need %i\n",f->bytesneeded);*/ | ||||
| 		*((uint32_t*)(r))=f->bytesneeded; | ||||
| 		*((uint32_t*)(r+MAX_PKT_HDR_LEN))=f->bytesneeded; | ||||
| 		return r;  | ||||
| 	} | ||||
|  | ||||
| /*//	printf("Fragman bytes needed: %i, received  %i\n",f->bytesneeded,f->bytesreceived);*/ | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -19,9 +19,9 @@ | ||||
|  | ||||
| /** | ||||
|  *@defgroup Fragman FRAGMAN | ||||
|  *@breif Frgaman functions | ||||
|  *@brief Frgaman functions | ||||
|  * | ||||
|  * Detailed esription | ||||
|  * Detailed desription | ||||
|  *@{ | ||||
|  */ | ||||
|  | ||||
| @ -33,18 +33,18 @@ | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #ifndef FRAG_MAXSIZE | ||||
| 	/** maximaum size of a fragment */ | ||||
| 	#define FRAG_MAXSIZE 65536+4 | ||||
| #endif | ||||
|  | ||||
| #ifndef FRAG_MAXIDS | ||||
| 	#define FRAG_MAXIDS 10 | ||||
| #endif | ||||
| #define MAX_PKT_HDR_LEN 64 | ||||
|  | ||||
| #ifndef FRAG_TTL | ||||
| 	#define FRAG_TTL 5 | ||||
| #endif | ||||
| /** maximaum size of a fragment */ | ||||
| #define FRAG_MAXSIZE (65536+MAX_PKT_HDR_LEN) | ||||
|  | ||||
| #define FRAG_MAXIDS 10 | ||||
|  | ||||
| /** | ||||
|  * TTL of received fragment in seconds | ||||
|  */ | ||||
| #define FRAG_TTL 5  | ||||
|  | ||||
|  | ||||
| struct frag { | ||||
| @ -57,7 +57,7 @@ struct frag { | ||||
| 	int bytesreceived; | ||||
| 	int bytesneeded; | ||||
| 	struct timespec t; | ||||
| 	uint8_t * header; | ||||
| //	uint8_t * header; | ||||
| }; | ||||
|  | ||||
| typedef struct frag frag_t; /*FRAGMAN;*/ | ||||
|  | ||||
| @ -137,7 +137,7 @@ | ||||
| #define LW_ELEM_DIRECT_SEQUENCE_CONTROL			14 | ||||
|  | ||||
| #define LW_ELEM_CHANGE_STATE_EVENT			26 | ||||
| #define LW_ELEM_80211_DELETE_WLAN			28 | ||||
| #define LWAPP_ELEM_80211_DELETE_WLAN			28 | ||||
|  | ||||
| #define LW_ELEM_AC_NAME					31 | ||||
| #define LW_ELEM_LOCATION_DATA				35 | ||||
| @ -151,7 +151,7 @@ | ||||
|  | ||||
| #define LW_ELEM_CERTIFICATE				44 | ||||
| #define LW_ELEM_WTP_BOARD_DATA				50 | ||||
| #define LW_BCAST_SSID_MODE				51 | ||||
| #define LWAPP_ELEM_BCAST_SSID_MODE			51 | ||||
| #define LW_ELEM_WTP_MODE_AND_TYPE			54 | ||||
| #define LW_ELEM_QOS					57 | ||||
|  | ||||
|  | ||||
| @ -38,16 +38,16 @@ int cw_encode_elements(struct cw_ElemHandlerParams *params, mlist_t elements_lis | ||||
| 			} | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| /* | ||||
| 		if (!data->mand){ | ||||
| 			if (!cw_cfg_base_exists(params->cfg_list[0],handler->key)){ | ||||
| 				cw_dbg(DBG_MSG_COMPOSE,"    Add Elem: %d %d %d %s - (skip)",  | ||||
| 						data->proto, data->vendor, data->id, handler->name); | ||||
| 				cw_dbg(DBG_MSG_COMPOSE,"    Add Elem: %d %d %d %s %s - (skip)",  | ||||
| 						data->proto, data->vendor, data->id, handler->name, handler->key); | ||||
|  | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| */ | ||||
|  | ||||
| 		l = handler->put(handler,params,dst+len); | ||||
| 		cw_dbg(DBG_MSG_COMPOSE,"    Add Elem: %d %d %d %s - (%d bytes)",  | ||||
| @ -233,6 +233,10 @@ int cw_decode_element(struct cw_ElemHandlerParams *params, int proto, | ||||
|  | ||||
| 	/* check the length of the message */ | ||||
| 	if (len < handler->min_len) { | ||||
| 		if (!handler->flags || cw_dbg_is_level(DBG_ELEM_VNDR)) | ||||
| 			cw_dbg_elem(params->dbg_level, NULL, params->msgdata->type, handler, | ||||
| 				    data, len); | ||||
| 		 | ||||
| 		cw_dbg(DBG_ELEM_ERR, | ||||
| 		       "%d (%s) message element too short, len=%d, min len=%d", | ||||
| 		       handler->id, handler->name, len, handler->min_len); | ||||
| @ -246,6 +250,10 @@ int cw_decode_element(struct cw_ElemHandlerParams *params, int proto, | ||||
|  | ||||
|  | ||||
| 	if (len > handler->max_len && handler->max_len) { | ||||
| 		if (!handler->flags || cw_dbg_is_level(DBG_ELEM_VNDR)) | ||||
| 			cw_dbg_elem(params->dbg_level, NULL, params->msgdata->type, handler, | ||||
| 				    data, len); | ||||
| 			 | ||||
| 		cw_dbg(DBG_ELEM_ERR, | ||||
| 		       "%d (%s) message element too big, len=%d, max len=%d", | ||||
| 		       handler->id, handler->name, len, handler->max_len); | ||||
|  | ||||
							
								
								
									
										13
									
								
								src/cw/mod.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/cw/mod.c
									
									
									
									
									
								
							| @ -139,14 +139,14 @@ struct cw_Mod *cw_mod_load(const char *mod_name, cw_Cfg_t * global_cfg, int role | ||||
| 	/* Search for the module in mods_loaded, to see if it is | ||||
| 	 * already loaded or was statically linked */ | ||||
|  | ||||
| 	cw_dbg(DBG_MOD, "MOD: Load module '%s'", mod_name); | ||||
| 	cw_dbg(DBG_MOD, "Loading module '%s'.", mod_name); | ||||
|  | ||||
| 	memset(&search, 0, sizeof(search)); | ||||
| 	search.name = mod_name; | ||||
|  | ||||
| 	mod = mavl_get_ptr(mods_loaded, &search); | ||||
| 	if (mod) { | ||||
| 		cw_dbg(DBG_MOD, "MOD: Module already loaded '%s'", mod_name); | ||||
| 		cw_dbg(DBG_MOD, "Module already loaded: '%s'.", mod_name); | ||||
| 		return mod; | ||||
| 	} | ||||
|  | ||||
| @ -165,7 +165,7 @@ struct cw_Mod *cw_mod_load(const char *mod_name, cw_Cfg_t * global_cfg, int role | ||||
| 	if (filename == NULL) | ||||
| 		return NULL; | ||||
|  | ||||
| 	cw_dbg(DBG_MOD, "MOD: loading module from file: %s", filename); | ||||
| 	cw_dbg(DBG_MOD, "Loading module from file: %s", filename); | ||||
|  | ||||
| 	/* Open the DLL */ | ||||
| 	handle = dlopen(filename, RTLD_NOW); | ||||
| @ -189,8 +189,11 @@ struct cw_Mod *cw_mod_load(const char *mod_name, cw_Cfg_t * global_cfg, int role | ||||
| 		goto errX; | ||||
| 	} | ||||
|  | ||||
| 	cw_dbg(DBG_MOD, "MOD: %s sucessfull loaded, calling init now.", filename); | ||||
| 	mod->init(mod, global_cfg, role); | ||||
| 	cw_dbg(DBG_MOD, "Module %s sucessfull loaded, calling init now.", filename); | ||||
| 	if (!mod->init(mod, global_cfg, role)){ | ||||
| 		dlclose(handle); | ||||
| 		mod=NULL; | ||||
| 	}		 | ||||
| 	 | ||||
|       errX: | ||||
| 	free(filename); | ||||
|  | ||||
| @ -56,7 +56,7 @@ struct cw_Mod { | ||||
| 		int elems_len, struct sockaddr * from, int mode); | ||||
|  | ||||
|  | ||||
| 	struct cw_MsgSet * (*register_messages)(struct cw_MsgSet * set, int mode); | ||||
| 	struct cw_MsgSet * (*register_messages)(struct cw_MsgSet * set, int mode ); | ||||
| 	 | ||||
| 	/**  | ||||
| 	 * Handle returned by dlopen, if this module was loaded  | ||||
|  | ||||
| @ -223,7 +223,7 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata, | ||||
| 				break; | ||||
| 				continue; | ||||
| 			case CW_DELETE: | ||||
| 				cw_dbg(DBG_MOD, "  deleting message element %d %d %d - %s", | ||||
| 				cw_dbg(DBG_MOD_DETAIL, "  deleting message element %d %d %d - %s", | ||||
| 				       elemdef->proto, | ||||
| 				       elemdef->vendor, elemdef->id, handler->name); | ||||
| 				 | ||||
| @ -248,11 +248,11 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata, | ||||
| 		result = mavl_replace(msgdata->elements_tree, &ed, &replaced); | ||||
|  | ||||
| 		if (!replaced) { | ||||
| 			cw_dbg(DBG_MOD, "  adding message element %d %d %d - %s", | ||||
| 			cw_dbg(DBG_MOD_DETAIL, "  adding message element %d %d %d - %s", | ||||
| 			       elemdef->proto, | ||||
| 			       elemdef->vendor, elemdef->id, handler->name); | ||||
| 		} else { | ||||
| 			cw_dbg(DBG_MOD, "  replacing message element %d %d %d - %s", | ||||
| 			cw_dbg(DBG_MOD_DETAIL, "  replacing message element %d %d %d - %s", | ||||
| 			       elemdef->proto, | ||||
| 			       elemdef->vendor, elemdef->id, handler->name); | ||||
| 		} | ||||
| @ -275,7 +275,7 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata, | ||||
| 						    result->vendor, result->id); | ||||
| 		if (result->mand){ | ||||
| 			mlist_append_ptr(msgdata->mand_keys,(void*)handler->key); | ||||
| 			cw_dbg(DBG_MOD,"    Add mandatory key: %s",handler->key); | ||||
| 			cw_dbg(DBG_MOD_DETAIL,"    Add mandatory key: %s",handler->key); | ||||
| 		} | ||||
| 		/*//printf("Have Result %d %d - %s\n",result->id,result->mand, handler->key);*/ | ||||
| 	} | ||||
| @ -294,7 +294,7 @@ int cw_msgset_add(struct cw_MsgSet *set, | ||||
| 	struct cw_MsgDef *msgdef; | ||||
| 	/* Create mavl for all handlers */ | ||||
| 	for (handler = handlers; handler->id; handler++) { | ||||
| 		cw_dbg(DBG_MOD, "Adding handler for element %d - %s - with key: %s", | ||||
| 		cw_dbg(DBG_MOD_DETAIL, "Adding handler for element %d - %s - with key: %s", | ||||
| 		       handler->id, handler->name, handler->key); | ||||
| 		mavl_replace(set->handlers_by_id, handler, NULL); | ||||
| 		mavl_replace(set->handlers_by_key, handler, NULL); | ||||
| @ -339,7 +339,7 @@ int cw_msgset_add(struct cw_MsgSet *set, | ||||
| 		msg->receiver = msgdef->receiver; | ||||
|  | ||||
|  | ||||
| 		cw_dbg(DBG_MOD, "Add message Type:%d - %s ", msgdef->type, msgdef->name); | ||||
| 		cw_dbg(DBG_MOD_DETAIL, "Add message Type:%d - %s ", msgdef->type, msgdef->name); | ||||
|  | ||||
|  | ||||
| 		update_msgdata(set, msg, msgdef); | ||||
| @ -376,7 +376,7 @@ int cw_msgset_add_states(struct cw_MsgSet * set, cw_StateMachineState_t * states | ||||
| 		else{ | ||||
| 			repstr = "Adding"; | ||||
| 		} | ||||
| 		cw_dbg(DBG_MOD,"%s machine state : [%s->%s]",repstr, | ||||
| 		cw_dbg(DBG_MOD_DETAIL,"%s machine state : [%s->%s]",repstr, | ||||
| 			cw_strstate(s->prevstate), | ||||
| 			cw_strstate(s->state)); | ||||
| 		s++; | ||||
| @ -405,7 +405,9 @@ struct cw_MsgData *cw_msgset_get_msgdata(struct cw_MsgSet *set, int type) | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len); | ||||
| //typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len); | ||||
| // | ||||
| /* | ||||
| cw_MsgCallbackFun cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id, | ||||
| 	cw_MsgCallbackFun fun) | ||||
|  | ||||
| @ -420,5 +422,5 @@ cw_MsgCallbackFun cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id, | ||||
| 	return old_callback; | ||||
| } | ||||
|  | ||||
|  | ||||
| */ | ||||
|  | ||||
|  | ||||
| @ -72,6 +72,9 @@ struct cw_MsgSet { | ||||
| 	mavl_t statemachine_states; | ||||
| 	int (*write_header)(struct cw_ElemHandler * handler, uint8_t * dst, int len); | ||||
| 	int (*header_len)(struct cw_ElemHandler *handler); | ||||
| 	int (*format_pkt_hdr)(char *dst, int incomming, uint8_t * packet, int len, | ||||
| 		      struct sockaddr *from); | ||||
| 	 | ||||
| }; | ||||
|  | ||||
|  | ||||
| @ -146,9 +149,8 @@ struct cw_ElemHandler * cw_msgset_get_elemhandler(struct cw_MsgSet * set, | ||||
| #define CW_MSGSET_POSTPROCESS	1 | ||||
| #define CW_MSGSET_PREPROCESS	2 | ||||
|  | ||||
| typedef int (*cw_MsgCallbackFun)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len); | ||||
| cw_MsgCallbackFun cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id, | ||||
| 	cw_MsgCallbackFun fun); | ||||
| //cw_MsgCallbackFun cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id, | ||||
| //	cw_MsgCallbackFun fun); | ||||
|  | ||||
|  | ||||
| #endif | ||||
|  | ||||
| @ -1,51 +0,0 @@ | ||||
| /* | ||||
|     This file is part of libcapwap. | ||||
|  | ||||
|     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 __RADIOINFO_H | ||||
| #define __RADIOINFO_H | ||||
|  | ||||
| #include "bstr.h" | ||||
|  | ||||
|  | ||||
| struct radioinfo{ | ||||
| 	char set; | ||||
| 	int rid; | ||||
| 	uint32_t type; | ||||
| 	int admin_state; | ||||
| 	int state; | ||||
| 	int cause; | ||||
| 	bstr_t rmac; | ||||
|  | ||||
| 	uint16_t regDomain; | ||||
|  | ||||
| 	uint8_t country_str[4]; | ||||
| 	uint8_t country_str2[4]; | ||||
|  | ||||
| 	int cfp_period; | ||||
| 	int cfp_max_duration; | ||||
| 	int beacon_period; | ||||
| 	int dtim_period; | ||||
| 	int max_bssid; | ||||
| 	int occupancy_limit; | ||||
|  | ||||
| 	bstr_t bssid;	 | ||||
| 	 | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @ -1,89 +0,0 @@ | ||||
| /* | ||||
|     This file is part of libcapwap. | ||||
|  | ||||
|     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/>. | ||||
|  | ||||
| */ | ||||
|  | ||||
| /** | ||||
|  * @file | ||||
|  * @brief bstr_create_from_cfgstr function | ||||
|  */ | ||||
|  | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include "bstr.h" | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Create a bstr16_t string from a string read from config file. | ||||
|  *  | ||||
|  * @param s String from config file. | ||||
|  * @return The create bstr_t string. | ||||
|  * | ||||
|  * The string from config file is an ASCII-text which is interpreted | ||||
|  * as hexadecimal string if it starts with ".x" | ||||
|  * | ||||
|  * @see bstr16_t | ||||
|  */ | ||||
| uint8_t * bstr16_create_from_cfgstr(const char * s) | ||||
| { | ||||
| 	int l = strlen(s); | ||||
|  | ||||
| 	 | ||||
| 	if (s[0]!='.') | ||||
| 		return bstr16_create((uint8_t*)s,l); | ||||
|  | ||||
| 	if (l<=2) | ||||
| 		return bstr16_create((uint8_t*)s,l); | ||||
|  | ||||
| 	if (s[1]=='.') | ||||
| 		return bstr16_create((uint8_t*)s+1,l-1); | ||||
|  | ||||
| 	if (s[1]=='x'){ | ||||
| 		uint8_t * ns=0; | ||||
| 		int len=0; | ||||
|  | ||||
| 		int ch,cl; | ||||
| 		const char *ss = s+2; | ||||
| 		int rc ; | ||||
| 		do { | ||||
| 			rc = sscanf(ss,"%01X",&ch); | ||||
| 			if (rc!=1) | ||||
| 				break; | ||||
| 			ss++; | ||||
| 			rc = sscanf(ss,"%01X",&cl); | ||||
| 			if (rc!=1) | ||||
| 				cl=0; | ||||
| 			ss++; | ||||
| 			int c=(ch<<4) | cl; | ||||
| 			 | ||||
| 			len++; | ||||
| 			ns = realloc(ns,len); | ||||
| 			ns[len-1]=c; | ||||
|  | ||||
|  | ||||
| 		}while (rc==1); | ||||
|  | ||||
|  | ||||
| 		return bstr16_create(ns,len); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -1,67 +0,0 @@ | ||||
|  | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include "bstr.h" | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Create a bstr1616_t string from a string read from config file. | ||||
|  *  | ||||
|  * @param s String from config file. | ||||
|  * @return The create bstr16_t string. | ||||
|  * | ||||
|  * The string from config file is an ASCII-text which is interpreted | ||||
|  * as hexadecimal string if it starts with ".x" | ||||
|  * | ||||
|  * @see bstr16_t | ||||
|  */ | ||||
| uint8_t * bstr16cfgstr(const char * s) | ||||
| { | ||||
| 	int l = strlen(s); | ||||
|  | ||||
| 	 | ||||
| 	if (s[0]!='.') | ||||
| 		return bstr16_create((uint8_t*)s,l); | ||||
|  | ||||
| 	if (l<=2) | ||||
| 		return bstr16_create((uint8_t*)s,l); | ||||
|  | ||||
| 	if (s[1]=='.') | ||||
| 		return bstr16_create((uint8_t*)s+1,l-1); | ||||
|  | ||||
| 	if (s[1]=='x'){ | ||||
| 		uint8_t * ns=0; | ||||
| 		int len=0; | ||||
|  | ||||
| 		int ch,cl; | ||||
| 		const char *ss = s+2; | ||||
| 		int rc ; | ||||
| 		do { | ||||
| 			rc = sscanf(ss,"%01X",&ch); | ||||
| 			if (rc!=1) | ||||
| 				break; | ||||
| 			ss++; | ||||
| 			rc = sscanf(ss,"%01X",&cl); | ||||
| 			if (rc!=1) | ||||
| 				cl=0; | ||||
| 			ss++; | ||||
| 			int c=(ch<<4) | cl; | ||||
| 			 | ||||
| 			len++; | ||||
| 			ns = realloc(ns,len); | ||||
| 			ns[len-1]=c; | ||||
|  | ||||
|  | ||||
| 		}while (rc==1); | ||||
|  | ||||
|  | ||||
| 		return bstr16_create(ns,len); | ||||
|  | ||||
|  | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -1,90 +0,0 @@ | ||||
| /* | ||||
|     This file is part of libcapwap. | ||||
|  | ||||
|     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/>. | ||||
|  | ||||
| */ | ||||
|  | ||||
| /** | ||||
|  * @file | ||||
|  * @brief bstr_create_from_cfgstr function | ||||
|  */ | ||||
|  | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include "bstr.h" | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Create a bstr_t string from a string read from config file. | ||||
|  *  | ||||
|  * @param s String from config file. | ||||
|  * @return The create bstr_t string. | ||||
|  * | ||||
|  * The string from config file is an ASCII-text which is interpreted | ||||
|  * as hexadecimal string if it starts with ".x" | ||||
|  * | ||||
|  * @see bstr_t | ||||
|  */ | ||||
| uint8_t * bstr_create_from_cfgstr(const char * s) | ||||
| { | ||||
| 	int l = strlen(s); | ||||
|  | ||||
| 	 | ||||
| 	if (s[0]!='.') | ||||
| 		return bstr_create((uint8_t*)s,l); | ||||
|  | ||||
| 	if (l<=2) | ||||
| 		return bstr_create((uint8_t*)s,l); | ||||
|  | ||||
| 	if (s[1]=='.') | ||||
| 		return bstr_create((uint8_t*)s+1,l-1); | ||||
|  | ||||
| 	if (s[1]=='x'){ | ||||
| 		uint8_t * ns=0; | ||||
| 		int len=0; | ||||
|  | ||||
| 		int ch,cl; | ||||
| 		const char *ss = s+2; | ||||
| 		int rc ; | ||||
| 		do { | ||||
| 			rc = sscanf(ss,"%01X",&ch); | ||||
| 			if (rc!=1) | ||||
| 				break; | ||||
| 			ss++; | ||||
| 			rc = sscanf(ss,"%01X",&cl); | ||||
| 			if (rc!=1) | ||||
| 				cl=0; | ||||
| 			ss++; | ||||
| 			int c=(ch<<4) | cl; | ||||
| 			 | ||||
| 			len++; | ||||
| 			ns = realloc(ns,len); | ||||
| 			ns[len-1]=c; | ||||
|  | ||||
|  | ||||
| 		}while (rc==1); | ||||
|  | ||||
|  | ||||
| 		return bstr_create(ns,len); | ||||
|  | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -1,38 +0,0 @@ | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "bstr.h" | ||||
| #include "cw_util.h" | ||||
|  | ||||
| int bstr_to_str(char *dst, bstr_t str,char * def) | ||||
| { | ||||
| 	if (!str){ | ||||
| 		if (!def)  | ||||
| 			return 0; | ||||
| 		return sprintf(dst,"%s",def); | ||||
| 	} | ||||
|  | ||||
| 	int printable = cw_is_printable(bstr_data(str),bstr_len(str)); | ||||
| 	int l=bstr_len(str); | ||||
|  | ||||
| 	if (printable){ | ||||
| 		memcpy((char*)dst,bstr_data(str),l); | ||||
| 		*(dst+l)=0; | ||||
| 		return l; | ||||
| 	} | ||||
|  | ||||
| 	int i; | ||||
| 	int c=0; | ||||
| 	char *s = dst;  | ||||
| 	for (i=0; i<l; i++){ | ||||
| 		if (!c){ | ||||
|  | ||||
| 			s += sprintf(s,"%02X",bstr_data(str)[i]); | ||||
| 			c=1; | ||||
| 		} | ||||
| 		else | ||||
| 			s += sprintf(s,",%02X",bstr_data(str)[i]); | ||||
| 	}	 | ||||
|  | ||||
| 	return s-dst; | ||||
| } | ||||
| @ -1,126 +0,0 @@ | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include "capwap80211_types.h" | ||||
| #include "dot11.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  | ||||
| static int to_str(void *item,char *dst) | ||||
| { | ||||
| 	mbag_item_t *it= item; | ||||
|  | ||||
| 	uint8_t *data = (uint8_t*)it->u2.data; | ||||
| 	int n=*data; | ||||
| 	data++; | ||||
|  | ||||
| 	char *d=dst; | ||||
| 	char *space=""; | ||||
| 	int i; | ||||
| 	for (i=0; i<n; i++){ | ||||
| 		int val = data[i]; | ||||
|  | ||||
|  | ||||
| 		d+=sprintf(d,"%s",space); | ||||
| 		if (val & 0x80){ | ||||
| 			d+=sprintf(d,"*"); | ||||
| 		} | ||||
| 		 | ||||
| 		d+=sprintf(d,"%0.1f",dot11_rate2float(val & 0x7f)); | ||||
|  | ||||
| 		space=" "; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return d-dst;	 | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static struct mbag_item *  from_str(const char *src) | ||||
| { | ||||
| 	mbag_item_t * item = mbag_item_new(CAPWAP80211_TYPE_RATESET); | ||||
| 	if (!item) | ||||
| 		return NULL; | ||||
|  | ||||
| 	if (strlen(src)==0) | ||||
| 		return 0; | ||||
|  | ||||
| 	uint8_t rates[64]; | ||||
| 	int nrates =0; | ||||
|  | ||||
| 	const char *s = src; | ||||
|  | ||||
| 	while (*s!=0){ | ||||
| 		while (*s==' ')  | ||||
| 			s++; | ||||
| 		int m=0; | ||||
| 		if(*s=='*'){ | ||||
| 			m=0x80; | ||||
| 			s++; | ||||
| 		} | ||||
| 		else{ | ||||
| 			m=0; | ||||
| 		} | ||||
| 	 | ||||
| 		float val; | ||||
| 		int n=sscanf(s,"%f",&val); | ||||
| 		if (n!=1) | ||||
| 			break; | ||||
| 		 | ||||
| 		int r = dot11_float2rate(val) | m; | ||||
|  | ||||
| 		rates[nrates++]=r; | ||||
|  | ||||
|  | ||||
| 		while (*s!=0 && *s!=' ') | ||||
| 			s++; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	uint8_t *data = malloc(nrates+1); | ||||
| 	*data=nrates; | ||||
| 	memcpy(data+1,rates,nrates); | ||||
|  | ||||
| 	item->u2.data=data; | ||||
|  | ||||
|  | ||||
| 	return item; | ||||
| } | ||||
|  | ||||
| static struct mbag_item *  get(const uint8_t *src,int len) | ||||
| { | ||||
|  | ||||
| 	mbag_item_t * item = mbag_item_new(CAPWAP80211_TYPE_RATESET); | ||||
| 	if (!item) | ||||
| 		return NULL; | ||||
|  | ||||
| 	uint8_t *data = malloc(len+1); | ||||
| 	if (!data){ | ||||
| 		free (item); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	*data=len; | ||||
| 	memcpy(data+1,src,len); | ||||
| 	item->u2.data=data; | ||||
| 	return item; | ||||
| } | ||||
|  | ||||
| static  int put(struct mbag_item *i,uint8_t *dst) | ||||
| { | ||||
| 	int l=*((uint8_t*)(i->u2.data)); | ||||
| 	memcpy(dst,i->u2.data+1,l); | ||||
| 	return l; | ||||
| } | ||||
|  | ||||
|  | ||||
| const struct mbag_typedef capwap80211_type_rateset = { | ||||
| 	.name = "802.11 Rate Set", | ||||
| 	.del = free, | ||||
| 	.from_str = from_str, | ||||
| 	.to_str = to_str, | ||||
| 	.get = get, | ||||
| 	.put = put | ||||
| }; | ||||
| */ | ||||
| @ -1,59 +0,0 @@ | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Add a Cisco AP Timesync message element to a buffer | ||||
|  * @param dst destination buffer | ||||
|  * @param time a unix timestamp | ||||
|  * @param type of time | ||||
|  * @return number of bytes put (5) | ||||
|  */ | ||||
| /* | ||||
| int cw_put_cisco_ap_timesync(uint8_t * dst, time_t time, uint8_t type) | ||||
| { | ||||
| 	cw_put_dword(dst , time); | ||||
| 	cw_put_byte(dst + 4, type); | ||||
| 	return 5; | ||||
|  | ||||
| } | ||||
| */ | ||||
|  | ||||
| /* | ||||
| int cw_addelem_cisco_ap_regulatory_domain(uint8_t *dst, struct radioinfo * ri){ | ||||
| 	uint8_t *d=dst+10; | ||||
| 	 | ||||
| 	d+=cw_put_byte(d,ri->rid);	// Band ID  | ||||
| 	d+=cw_put_byte(d,1);		// Set True/False  | ||||
| 	d+=cw_put_byte(d,ri->rid);	// Slot ID  | ||||
| 	d+=cw_put_word(d,ri->regDomain); | ||||
| 	return 5 + cw_put_elem_vendor_hdr(dst, CW_VENDOR_ID_CISCO, CW_CISCO_AP_REGULATORY_DOMAIN, 5); | ||||
| } | ||||
| */ | ||||
|  | ||||
| /**  | ||||
|  * Add a Cisco Certificate payload message element | ||||
|  * @param dst destination buffer | ||||
|  * @param src pointer to DER certificate | ||||
|  * @param len length of certificate | ||||
|  * @return number of bytes put | ||||
|  */ | ||||
| /* | ||||
| int cw_addelem_cisco_certificate(uint8_t*dst,uint8_t*src,int len){ | ||||
| 	int l = lw_put_certificate(dst+10,src,len); | ||||
| 	return l+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_CERTIFICATE,l); | ||||
| } | ||||
| */ | ||||
|  | ||||
| /* | ||||
| int cw_addelem_cisco_wtp_radio_cfg(uint8_t * dst,struct radioinfo *ri){ | ||||
| 	int l = lw_put_80211_wtp_wlan_radio_configuration(dst+10,ri); | ||||
| 	return l+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_STATION_CFG,l); | ||||
| } | ||||
| */ | ||||
|  | ||||
| /* | ||||
| int cw_readelem_cisco_station_cfg(uint8_t *src,int len){ | ||||
| 	 | ||||
| //	lw_readelem_ | ||||
| 	return 0; | ||||
| } | ||||
| */ | ||||
| @ -1,175 +0,0 @@ | ||||
| #include "capwap.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "radio.h" | ||||
| #include "log.h" | ||||
| #include "dbg.h" | ||||
|  | ||||
| /* | ||||
| int cw_put_cisco_wtp_radio_cfg(uint8_t *dst, int rid, mbag_t radio) | ||||
| { | ||||
|  | ||||
| 	cw_put_byte(dst,rid); | ||||
|  | ||||
| 	cw_put_byte(dst+1,0); //? | ||||
| 	cw_put_word(dst+2,mbag_get_word(radio,CW_RADIO_OCCUPANCY_LIMIT,12)); | ||||
| 	cw_put_byte(dst+4,mbag_get_byte(radio,CW_RADIO_CFP_PERIOD,8)); | ||||
|  | ||||
| 	cw_put_word(dst+5,mbag_get_word(radio,CW_RADIO_CFP_MAX_DURATION,200)); | ||||
|  | ||||
|  | ||||
| 	bstr_t	grmac = mbag_get_bstr(radio,CW_RADIO_BSSID,NULL); | ||||
|  | ||||
| //printf("GRMAC: %d\n",bstr_len(grmac)); | ||||
| 	if ( grmac) { | ||||
| 		if (bstr_len(grmac)!=6){ | ||||
| 			cw_log(LOG_ERR,"Wrong bssid size"); | ||||
| exit(0); | ||||
| 			grmac =NULL; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	bstr_t rmac; | ||||
|  | ||||
| 	if (!grmac){ | ||||
| 		uint8_t defrmac[]={0,0,0,0,0,0}; | ||||
| 		rmac = bstr_create(defrmac,6); | ||||
| 	} | ||||
| 	else | ||||
| 		rmac = grmac; | ||||
| 		 | ||||
|  | ||||
| 	cw_put_bstr(dst+7,rmac); | ||||
|  | ||||
| 	if ( !grmac ) | ||||
| 		free(rmac); | ||||
| 	 | ||||
| 	cw_put_word(dst+13,0); // beacon period | ||||
|  | ||||
|  | ||||
| 	cw_put_data(dst+15,mbag_get_raw(radio,CW_RADIO_COUNTRY_STRING,"DE "),3); | ||||
| 	cw_put_data(dst+18,mbag_get_raw(radio,CW_RADIO_COUNTRY_STRING,"DE "),3); | ||||
|  | ||||
| 	cw_put_byte(dst+21,10); // gPeriod | ||||
|  | ||||
| 	cw_put_dword(dst+22,0x3538);	// ? | ||||
|  | ||||
| 	cw_put_word(dst+26,0); | ||||
|  | ||||
| 	return 26+2; //+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_WTP_RADIO_CFG,28); | ||||
| } | ||||
|  | ||||
| */ | ||||
|  | ||||
| /* | ||||
| int cw_put_elem_cisco_ap_regulatory_domain(uint8_t *dst,int rid, mbag_t radio) | ||||
| { | ||||
| 	//int l=0; | ||||
| 	uint8_t *d=dst+10; | ||||
| 	 | ||||
| 	d+=cw_put_byte(d,rid);		//Band ID  | ||||
| 	d+=cw_put_byte(d,1);		// Set True/False  | ||||
| 	d+=cw_put_byte(d,rid);		//* Slot ID  | ||||
| 	d+=cw_put_word(d,mbag_get_word(radio,CW_RADIO_REG_DOMAIN,1)); | ||||
|  | ||||
| 	return 5 + cw_put_elem_vendor_hdr(dst, CW_VENDOR_ID_CISCO, CW_CISCO_AP_REGULATORY_DOMAIN, 5); | ||||
| 	 | ||||
|  | ||||
| } | ||||
|  | ||||
| */ | ||||
|  | ||||
| /* | ||||
| int cw_put_elem_cisco_radio_cfg(uint8_t * dst,int rid, mbag_t radio) | ||||
| { | ||||
| 	int l = cw_put_cisco_wtp_radio_cfg(dst+10,rid,radio); | ||||
| 	return l+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_WTP_RADIO_CFG,l); | ||||
| } | ||||
|  | ||||
| int cw_out_cisco_wtp_radio_cfg(struct conn *conn, struct cw_action_out *a, uint8_t * dst) | ||||
| { | ||||
|  | ||||
| 	int l=0; | ||||
| 	MAVLITER_DEFINE(it,conn->radios); | ||||
| 	mavliter_foreach(&it){ | ||||
| 		struct mbag_item *i = mavliter_get(&it); | ||||
| 		if ( i->type != MBAG_MBAG ) { | ||||
| 			continue; | ||||
| 		} | ||||
| //		l+=cw_put_elem_radio_info(dst+l,i->id,i->data); | ||||
| 		l+=cw_put_elem_cisco_radio_cfg(dst+l,i->u1.iid,i->u2.data); | ||||
| 		l+=cw_put_elem_cisco_ap_regulatory_domain(dst+l,i->u1.iid,i->u2.data); | ||||
|  | ||||
| 	} | ||||
| 	return l; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //	MAVLITER_DEFINE | ||||
| //	int l = cw_out_cisco_wtp_radio_cfg_(conn,a,dst,0); | ||||
|  | ||||
| //	return l+cw_out_cisco_wtp_radio_cfg_(conn,a,dst+l,1); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_in_cisco_radio_cfg(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, | ||||
| 		  struct sockaddr *from) | ||||
| { | ||||
|  | ||||
| 	int rid = cw_get_byte(data); | ||||
| 	mbag_t radio = mbag_i_get_mbag(conn->radios,rid,NULL); | ||||
| 	if ( !radio){ | ||||
| 		cw_dbg(DBG_ELEM_ERR,"Radio ID %d not defined",rid); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
| //	printf("Here we are %d\n",rid); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_radio_cisco_set_state(struct conn * conn, uint8_t *data, int len, int cause) | ||||
| { | ||||
|  | ||||
| 	int rid = cw_get_byte(data); | ||||
| 	int state = cw_get_byte(data+1); | ||||
| 	if (rid != 255) | ||||
| 		return cw_radio_set_admin_state(conn->radios,rid,state,cause); | ||||
|  | ||||
|  | ||||
| 	MAVLITER_DEFINE(it,conn->radios); | ||||
| 	mavliter_foreach(&it){ | ||||
| 		mbag_item_t *i = mavliter_get(&it); | ||||
| 		cw_radio_set_admin_state(conn->radios,i->u1.iid,state,cause); | ||||
|  | ||||
| 	} | ||||
| 	return 1;	 | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_in_cisco_radio_administrative_state(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, | ||||
| 		  struct sockaddr *from) | ||||
| { | ||||
| 	return cw_radio_cisco_set_state(conn,data,len,-1);	 | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_in_cisco_radio_administrative_state_wtp(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, | ||||
| 		  struct sockaddr *from) | ||||
| { | ||||
| 	return cw_radio_cisco_set_state(conn,data,len,3);	 | ||||
| } | ||||
|  | ||||
|  | ||||
| */ | ||||
| @ -1,33 +0,0 @@ | ||||
|  | ||||
| #include "capwap.h" | ||||
|  | ||||
| #include "conn.h" | ||||
|  | ||||
| #include "mavl.h" | ||||
|  | ||||
| /* | ||||
| void conn_clear_upd(struct conn *conn, int merge) | ||||
| { | ||||
| 	if (merge){ | ||||
| 		mavl_merge(conn->config, conn->config_upd); | ||||
|  | ||||
| 		MAVLITER_DEFINE (it,conn->radios_upd); | ||||
|  | ||||
| 		mavliter_foreach(&it){ | ||||
| 			struct mbag_item * ruitem = mavliter_get(&it); | ||||
| 			mavl_t radio_upd = ruitem->u2.data; | ||||
|  | ||||
| 			mbag_t radio = mbag_i_get_mbag(conn->radios,ruitem->u1.iid,NULL); | ||||
| 			if (radio){ | ||||
| 				mavl_merge(radio,radio_upd); | ||||
| 			} | ||||
|  | ||||
| 		}		 | ||||
| 		 | ||||
| 	} | ||||
| 	mavl_del_all(conn->config_upd); | ||||
| 	mavl_del_all(conn->radios_upd); | ||||
|  | ||||
| } | ||||
|  | ||||
| */ | ||||
| @ -1,26 +0,0 @@ | ||||
| #include "capwap.h" | ||||
| #include "cw.h" | ||||
|  | ||||
| int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo *ri) | ||||
| { | ||||
| 	cw_put_byte(dst+10,ri->rid); | ||||
| 	cw_put_byte(dst+10+1,0); | ||||
| 	cw_put_word(dst+10+2,ri->occupancy_limit); | ||||
| 	cw_put_byte(dst+10+4,ri->cfp_period); | ||||
| 	cw_put_word(dst+10+5,ri->cfp_max_duration); | ||||
|  | ||||
| 	/* XXX catch rmac shorter or longer than 6*/ | ||||
|  | ||||
| 	cw_put_bstr(dst+10+7,ri->rmac);	/* length MUST be 6 */ | ||||
| 	 | ||||
| 	cw_put_word(dst+10+13,ri->beacon_period); | ||||
| 	cw_put_data(dst+10+15,ri->country_str,3); | ||||
| 	cw_put_data(dst+10+18,ri->country_str2,3); | ||||
|  | ||||
| 	cw_put_byte(dst+10+21,10); // gPeriod | ||||
|  | ||||
| 	cw_put_dword(dst+10+22,0x3538);	// ? | ||||
|  | ||||
| /*	return 28+cw_put_elem_vendor_hdr(dst,CW_VENDOR_ID_CISCO,CW_CISCO_WTP_RADIO_CFG,28);*/ | ||||
| } | ||||
|  | ||||
| @ -1,18 +0,0 @@ | ||||
| #include "cw.h" | ||||
| #include "dbg.h" | ||||
| #include "cw_80211.h" | ||||
|  | ||||
| /* | ||||
| int cw_in_80211_mac_operation(struct conn *conn, struct cw_action_in *a, uint8_t * data, | ||||
| 			 int len, struct sockaddr *from) | ||||
| { | ||||
| 	int rid = cw_get_byte(data); | ||||
| 	mbag_t r = mbag_i_get_mbag(conn->radios,rid,NULL); | ||||
| 	if (!r){ | ||||
| 		cw_dbg(DBG_ELEM_ERR,"Radio %d not defined. Can't set mac operation."); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	return cw_read_80211_mac_operation(data+2,r); | ||||
| } | ||||
| */ | ||||
| @ -1,38 +0,0 @@ | ||||
|  | ||||
|  | ||||
| #include "dbg.h" | ||||
|  | ||||
| #include "capwap.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
| int cw_in_cisco_image_identifier(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len,struct sockaddr *from) | ||||
| { | ||||
|  | ||||
| 	if (len<a->min_len) { | ||||
| 		cw_dbg(DBG_ELEM_ERR,"Message element too short, %d < %d", len,a->min_len); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	uint32_t vendor_id = cw_get_dword(data); | ||||
| 	int dstart; | ||||
|  | ||||
| 	switch (vendor_id) { | ||||
| 		case CW_VENDOR_ID_ZYXEL: | ||||
| 		case CW_VENDOR_ID_CISCO: | ||||
| 		case CW_VENDOR_ID_FSF: | ||||
| 		case 0: | ||||
| 			dstart=4; | ||||
| 			len-=4; | ||||
| 			break; | ||||
| 		default: | ||||
| 			vendor_id=CW_VENDOR_ID_CISCO; | ||||
| 			dstart=0; | ||||
| 	} | ||||
|  | ||||
| //	mbag_set(conn->remote,a->item_id,a->itemtype,data+dstart,len); | ||||
| //	mbag_set_bstrv(conn->incomming,a->item_id,vendor_id,data+dstart,len); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| */ | ||||
| @ -1,22 +0,0 @@ | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "dbg.h" | ||||
| #include "log.h" | ||||
|  | ||||
| #include "cw.h" | ||||
| #include "radio.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_in_radio_administrative_state(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, | ||||
| 		  struct sockaddr *from) | ||||
| { | ||||
| /*	int rid = cw_get_byte(data); | ||||
| 	int state = cw_get_byte(data+1); | ||||
| 	return cw_radio_set_admin_state(conn->radios,rid,state,-1); | ||||
| */ | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,26 +0,0 @@ | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "dbg.h" | ||||
| #include "log.h" | ||||
|  | ||||
| #include "capwap.h" | ||||
| #include "radio.h" | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_in_radio_administrative_state_wtp(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, | ||||
| 		  struct sockaddr *from) | ||||
| { | ||||
|  | ||||
| 	if (!cw_in_radio_administrative_state(conn,a,data,len,from) )  | ||||
| 		return 0;  | ||||
|  | ||||
|  | ||||
| 	return 1; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,123 +0,0 @@ | ||||
| /* | ||||
|     This file is part of libcapwap. | ||||
|  | ||||
|     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 "cw.h" | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #include "cw_util.h" | ||||
| #include "dbg.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
| static void readsubelems_wtp_board_data(mbag_t itemstore, uint8_t * msgelem, | ||||
| 					int len) | ||||
| { | ||||
| 	if (len<4) | ||||
| 		return; | ||||
|  | ||||
| 	int i = 0; | ||||
| //	uint32_t val; | ||||
| 	do { | ||||
| //		val = ntohl(*((uint32_t *) (msgelem + i))); | ||||
| //		int subtype = (val >> 16) & 0xffff; | ||||
| //		int sublen = val & 0xffff; | ||||
| // | ||||
| 		int subtype = cw_get_word(msgelem+i); | ||||
| 		int sublen = cw_get_word(msgelem+i+2); | ||||
| 		i += 4; | ||||
| 		if (sublen + i > len) { | ||||
| 			cw_dbg(DBG_ELEM_ERR, | ||||
| 			       "WTP Board data sub-element too long, type=%d,len=%d", | ||||
| 			       subtype, sublen); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		cw_dbg(DBG_SUBELEM, "board data sub-element, type=%d (%s), len=%d", | ||||
| 		       subtype, cw_strboardelem(subtype),sublen); | ||||
|  | ||||
| 		cw_dbg_dmp(DBG_SUBELEM,msgelem+i,sublen,"Dump..."); | ||||
|  | ||||
| 		switch (subtype) { | ||||
| 			case CW_BOARDDATA_MODELNO: | ||||
| 				mbag_set_bstrn(itemstore, | ||||
| 						       CW_ITEM_WTP_BOARD_MODELNO, | ||||
| 						       msgelem + i, sublen); | ||||
| 				break; | ||||
| 			case CW_BOARDDATA_SERIALNO: | ||||
| 				mbag_set_bstrn(itemstore, | ||||
| 						       CW_ITEM_WTP_BOARD_SERIALNO, | ||||
| 						       msgelem + i, sublen); | ||||
|  | ||||
| 				break; | ||||
| 			case CW_BOARDDATA_MACADDRESS: | ||||
| 				mbag_set_bstrn(itemstore, | ||||
| 						       CW_ITEM_WTP_BOARD_MACADDRESS, | ||||
| 						       msgelem + i, sublen); | ||||
|  | ||||
| 				break; | ||||
| 			case CW_BOARDDATA_BOARDID: | ||||
| 				mbag_set_bstrn(itemstore, CW_ITEM_WTP_BOARD_ID, | ||||
| 						       msgelem + i, sublen); | ||||
| 				break; | ||||
| 			case CW_BOARDDATA_REVISION: | ||||
| 				mbag_set_bstrn(itemstore, | ||||
| 						       CW_ITEM_WTP_BOARD_REVISION, | ||||
| 						       msgelem + i, sublen); | ||||
| 			default: | ||||
| 				break; | ||||
| 		} | ||||
| 		i += sublen; | ||||
|  | ||||
| 	} while (i < len); | ||||
| } | ||||
|  | ||||
| */ | ||||
|  | ||||
| /** | ||||
|  * Parse a WTP Board Data messag element and put results to itemstore. | ||||
|  */ | ||||
|   | ||||
|   | ||||
|  /* | ||||
| int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data, | ||||
| 			 int len, struct sockaddr *from) | ||||
| { | ||||
|  | ||||
| 	if (len < 4) { | ||||
| 		cw_dbg(DBG_ELEM_ERR, | ||||
| 		       "Discarding WTP_BOARD_DATA msgelem, wrong size, type=%d, len=%d", | ||||
| 		       a->elem_id, len); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	mbag_t itemstore = conn->incomming; | ||||
| 	mbag_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR, cw_get_dword(data)); | ||||
|  | ||||
| 	readsubelems_wtp_board_data(itemstore, data + 4, len - 4); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
| */ | ||||
| @ -1,36 +0,0 @@ | ||||
| #include "cw.h" | ||||
| #include "capwap80211.h" | ||||
| #include "radio.h" | ||||
|  | ||||
| /* | ||||
| int cw_put_elem_80211_supported_rates(uint8_t*dst,int radio_id,mbag_t radio) | ||||
| { | ||||
|  | ||||
| 	struct mbag_item * sr = mbag_get(radio,CW_RADIO_SUPPORTED_RATES); | ||||
| 	if (!sr) | ||||
| 		return 0; | ||||
|  | ||||
| 	int n = cw_put_byte(dst+4,radio_id); | ||||
|  | ||||
| 	n+=cw_put_mbag_item(dst+5,sr); | ||||
| 	return 5 + cw_put_elem_hdr(dst,CW_ELEM80211_SUPPORTED_RATES,5); | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_out_80211_supported_rates(struct conn *conn, struct cw_action_out *a, uint8_t * dst) | ||||
| { | ||||
|  | ||||
| 	int l=0; | ||||
| 	MAVLITER_DEFINE(it,conn->radios); | ||||
| 	mavliter_foreach(&it){ | ||||
| 		struct mbag_item *i = mavliter_get(&it); | ||||
| 		if ( i->type != MBAG_MBAG ) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		l+=cw_put_elem_80211_supported_rates(dst+l,i->u1.iid,i->u2.data); | ||||
| 	} | ||||
| 	return l; | ||||
| } | ||||
|  | ||||
|  | ||||
| */ | ||||
| @ -1,42 +0,0 @@ | ||||
|  | ||||
|  | ||||
| #include "cw.h" | ||||
|  | ||||
|  | ||||
| #include "dbg.h" | ||||
| #include "log.h" | ||||
|  | ||||
| #include "acpriolist.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_put_ac_name_with_priority(uint8_t *dst,cw_acprio_t * acprio) | ||||
| { | ||||
| 	int len = strlen(acprio->name); | ||||
| 	cw_put_byte(dst,acprio->prio); | ||||
| 	cw_put_data(dst+1,(uint8_t*)acprio->name,len); | ||||
| 	return len+1; | ||||
| 	 | ||||
| } | ||||
|  | ||||
| int cw_out_ac_name_with_priority(struct conn *conn, struct cw_action_out *a, uint8_t * dst) | ||||
| { | ||||
| /*	cw_acpriolist_t prios = mbag_get_mavl(conn->config,CW_ITEM_AC_NAME_WITH_PRIORITY); | ||||
| 	if (!prios) | ||||
| 		return 0; | ||||
| 	 | ||||
| 	uint8_t *d = dst; | ||||
| 	 | ||||
| 	MAVLITER_DEFINE(it,prios); | ||||
| 	mavliter_foreach(&it){ | ||||
| 		cw_acprio_t * ac = mavliter_get(&it); | ||||
| 		 | ||||
| 		int l = cw_put_ac_name_with_priority(d+4,ac); | ||||
| 		d+=cw_put_elem_hdr(d,CW_ELEM_AC_NAME_WITH_PRIORITY,l)+l;		 | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	return d-dst; | ||||
| */ | ||||
| } | ||||
|  | ||||
| @ -1,57 +0,0 @@ | ||||
| /* | ||||
|     This file is part of libcapwap. | ||||
|  | ||||
|     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/>. | ||||
|  | ||||
| */ | ||||
|  | ||||
| /** | ||||
|  * @file  | ||||
|  * @brief Implementation output handler of capwap cw_out_local_ip_address | ||||
|  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netinet/in.h> | ||||
| #include <arpa/inet.h> | ||||
|  | ||||
| #include <string.h> | ||||
| #include "cw.h" | ||||
|  | ||||
|  | ||||
| #include "dbg.h" | ||||
| #include "log.h" | ||||
| #include "conn.h" | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Output handler for Capwap Local IP Address message element. | ||||
|  * | ||||
|  * @param conn Connection object | ||||
|  * @param action Pointer to action which called this handler | ||||
|  * @param dst Destination buffer | ||||
|  * | ||||
|  * This handler determines the IP address from #conn->sock. | ||||
|  * It can deal both with IPv4 and IPv6 sockets. | ||||
|  * | ||||
|  */ | ||||
|   | ||||
|  /* | ||||
| int cw_out_capwap_local_ip_address(struct conn *conn, struct cw_action_out *action, | ||||
| 				   uint8_t * dst) | ||||
| { | ||||
| 	return cw_put_local_ip_address(conn->sock,dst,CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS,CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS); | ||||
| } | ||||
|  | ||||
| */ | ||||
| @ -1,58 +0,0 @@ | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| #include "cw.h" | ||||
|  | ||||
|  | ||||
| #include "log.h" | ||||
| #include "dbg.h" | ||||
|  | ||||
|  | ||||
| #include "sock.h" | ||||
|  | ||||
| #include "lwapp.h" | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| int cw_out_image_data(struct conn *conn, struct cw_action_out *a, uint8_t * dst) | ||||
| { | ||||
| 	/* | ||||
| 	mbag_item_t * item = mbag_get(conn->outgoing,CW_ITEM_IMAGE_FILEHANDLE); | ||||
| 	if (!item) { | ||||
| 		cw_log(LOG_ERR,"Can't put element Image Data, no image filehandle found"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	FILE *infile = item->u2.data; | ||||
| 	if (infile==NULL){ | ||||
| 		cw_log(LOG_ERR,"Image Data Request infile = NULL"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	int bytes=0; | ||||
| 	switch ( conn->capwap_mode_out){ | ||||
| 		case CW_MODE_CISCO: | ||||
| 			bytes = lw_put_image_data(dst+4,infile); | ||||
| 			if ( bytes != LW_BLOCKSIZE_IMAGE_DATA + 3) { | ||||
|        		        	avltree_del(conn->outgoing, item); | ||||
| 			} | ||||
| 			break; | ||||
| 		default: | ||||
| 			bytes = cw_put_image_data(dst+4,infile); | ||||
| 			if (dst[4] != 1){ | ||||
|        		        	avltree_del(conn->outgoing, item); | ||||
| 			} | ||||
| 	} | ||||
|  | ||||
| 	if ( ferror(infile)){ | ||||
| 		cw_log(LOG_ERROR,"Aborting image data transfer: %s",strerror(errno)); | ||||
| 	} | ||||
|  | ||||
| 	return bytes + cw_put_elem_hdr(dst,a->elem_id,bytes); | ||||
| 	 */ | ||||
| 	 return 0; | ||||
| } | ||||
|  | ||||
| @ -1,50 +0,0 @@ | ||||
|  | ||||
|  | ||||
| /* | ||||
|  | ||||
| #include "cw.h" | ||||
| #include "cw/dbg.h" | ||||
|  | ||||
| int cw_out_radio_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst) | ||||
| { | ||||
| cw_dbg(DBG_X,"Radio Generic out %s",a->item_id); | ||||
| 	 | ||||
| 	int l=0; | ||||
| 	MAVLITER_DEFINE(it,conn->radios_upd); | ||||
| 	mavliter_foreach(&it){ | ||||
| 		struct mbag_item *radio = mavliter_get(&it); | ||||
| 		if ( radio->type != MBAG_MBAG ) { | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		// Size for msg elem header depends on  | ||||
| 		  // vendor specific payload  | ||||
| 		int start = a->vendor_id ? 10 : 4; | ||||
|  | ||||
| 		uint8_t * d = dst+l; | ||||
|  | ||||
|  | ||||
|  | ||||
| 		struct mbag_item * item = mbag_get(radio->u2.data,a->item_id); | ||||
| 		if (!item){ | ||||
| cw_dbg(DBG_X,"Not found! %s for rid %d",a->item_id,radio->u1.iid); | ||||
| 			continue; | ||||
| 		} | ||||
| 		int len=0; | ||||
| 		len += cw_put_byte(d+start,radio->u1.iid); | ||||
|  | ||||
| 	cw_dbg(DBG_X, "Radio generic out '%s' fro rid %d",a->item_id,radio->u1.iid); | ||||
| 		len += cw_put_mbag_item(d + start+1, item); | ||||
|  | ||||
| 		if (a->vendor_id) | ||||
| 			l+= len + cw_put_elem_vendor_hdr(d, a->vendor_id, a->elem_id, len); | ||||
| 		else | ||||
| 			l += len + cw_put_elem_hdr(d, a->elem_id, len); | ||||
|  | ||||
|  | ||||
|  | ||||
| 	} | ||||
| 	return l; | ||||
|  | ||||
| } | ||||
| */ | ||||
| @ -1,42 +0,0 @@ | ||||
|  | ||||
| #include "cw.h" | ||||
|  | ||||
|  | ||||
| #include "radio.h" | ||||
|  | ||||
| #include "dbg.h" | ||||
| #include "log.h" | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
| int cw_put_elem_radio_info(uint8_t*dst,int radio_id,mbag_t radio) | ||||
| { | ||||
| 	cw_put_byte(dst+4,radio_id); | ||||
| 	cw_put_dword(dst+5,mbag_get_dword(radio,CW_RADIOITEM80211_WTP_RADIO_INFORMATION,0)); | ||||
| 	return 5 + cw_put_elem_hdr(dst,CW_ELEM80211_WTP_RADIO_INFORMATION,5); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| int cw_out_radio_infos(struct conn *conn, struct cw_action_out *a, uint8_t * dst) | ||||
| { | ||||
|  | ||||
| 	int l=0; | ||||
| 	MAVLITER_DEFINE(it,conn->radios); | ||||
| 	mavliter_foreach(&it){ | ||||
| 		struct mbag_item *i = mavliter_get(&it); | ||||
| 		if ( i->type != MBAG_MBAG ) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		l+=cw_put_elem_radio_info(dst+l,i->u1.iid,i->u2.data); | ||||
|  | ||||
| 	} | ||||
| 	return l; | ||||
| 	  | ||||
| } | ||||
|  | ||||
| */ | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,80 +0,0 @@ | ||||
| #include "log.h" | ||||
| #include "capwap.h" | ||||
| #include "conn.h" | ||||
| #include "cw.h" | ||||
|  | ||||
| #define CW_MODE_CISCO 1 | ||||
|  | ||||
| static int cw_put_encryption_subelems(uint8_t *dst,int capwap_mode) | ||||
| { | ||||
| 	if (capwap_mode==CW_MODE_CISCO){ | ||||
| 		cw_put_word(dst,0x01); | ||||
| 		return 2; | ||||
| 	} | ||||
|  | ||||
| 	int n=2; | ||||
| 	 | ||||
| 	dst+=cw_put_byte(dst,n);	 | ||||
|  | ||||
| 	int i; | ||||
| 	for (i=0; i<n; i++){ | ||||
| 		dst+=cw_put_byte(dst,0); | ||||
| 		dst+=cw_put_byte(dst,0); | ||||
| 		dst+=cw_put_byte(dst,0); | ||||
| 	} | ||||
|  | ||||
| 	return 3*n+1; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
| int cw_out_wtp_descriptor(struct conn *conn, struct cw_action_out *a, uint8_t * dst) | ||||
| { | ||||
|  | ||||
| 	mbag_t mbag = conn->config; | ||||
|  | ||||
| 	// XXX Dummy WTP Descriptor Header | ||||
| 	uint8_t *d = dst+4; | ||||
|  | ||||
| 	d+=cw_put_byte(d,conn->radios->count);	//max radios | ||||
| 	d+=cw_put_byte(d,2);	//radios in use | ||||
|  | ||||
| 	d+=cw_put_encryption_subelems(d,conn->capwap_mode); | ||||
|  | ||||
| 	mbag_item_t * i; | ||||
| 	i = mbag_get(mbag,CW_ITEM_WTP_HARDWARE_VERSION); | ||||
| /*	if ( i ) {	 | ||||
| 	 	d += cw_put_version(d,CW_SUBELEM_WTP_HARDWARE_VERSION,i->u2.data); | ||||
| 	} | ||||
| 	else { | ||||
| 		cw_log(LOG_ERR, "Can't send Hardware Version in WTP Descriptor, not set."); | ||||
| 	} | ||||
|  | ||||
| 	i = mbag_get(mbag,CW_ITEM_WTP_SOFTWARE_VERSION); | ||||
| 	if ( i ) {	 | ||||
| 	 	d += cw_put_version(d,CW_SUBELEM_WTP_SOFTWARE_VERSION,i->u2.data); | ||||
| 	} | ||||
| 	else { | ||||
| 		cw_log(LOG_ERR, "Can't send Software Version in WTP descriptor, not set."); | ||||
| 	} | ||||
|  | ||||
|         i = mbag_get(mbag,CW_ITEM_WTP_BOOT_VERSION); | ||||
|         if ( i ) { | ||||
|                 d += cw_put_version(d,CW_SUBELEM_WTP_BOOTLOADER_VERSION,i->u2.data); | ||||
|         } | ||||
|         else { | ||||
|                 cw_log(LOG_INFO, "Can't send Boot Version in WTP descriptor, not set."); | ||||
|         } | ||||
|  | ||||
|         i = mbag_get(mbag,CW_ITEM_WTP_OTHER_VERSION); | ||||
|         if ( i ) { | ||||
|                 d += cw_put_version(d,CW_SUBELEM_WTP_OTHERSOFTWARE_VERSION,i->u2.data); | ||||
|         } | ||||
|         else { | ||||
|                 cw_log(LOG_INFO, "Can't send Other Version in WTP descriptor, not set."); | ||||
|         } | ||||
| * | ||||
| //	int len = d-dst-4; | ||||
| //	return len + cw_put_elem_hdr(dst,a->elem_id,len); | ||||
| }	 | ||||
| */ | ||||
| @ -1,56 +0,0 @@ | ||||
| /* | ||||
|     This file is part of libcapwap. | ||||
|  | ||||
|     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/>. | ||||
|  | ||||
| */ | ||||
|  | ||||
| /** | ||||
|  * @file  | ||||
|  * @brief Implementation output handler of capwap cw_out_local_ip_address | ||||
|  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netinet/in.h> | ||||
| #include <arpa/inet.h> | ||||
|  | ||||
| #include <string.h> | ||||
| #include "cw.h" | ||||
|  | ||||
|  | ||||
| #include "dbg.h" | ||||
| #include "log.h" | ||||
| #include "conn.h" | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Output handler for Capwap Local IP Address message element. | ||||
|  * | ||||
|  * @param conn Connection object | ||||
|  * @param action Pointer to action which called this handler | ||||
|  * @param dst Destination buffer | ||||
|  * | ||||
|  * This handler determines the IP address from #conn->sock. | ||||
|  * It can deal both with IPv4 and IPv6 sockets. | ||||
|  * | ||||
|  */ | ||||
|   | ||||
|  /* | ||||
| int cw_out_wtp_ip_address(struct conn *conn, struct cw_action_out *action, | ||||
| 				   uint8_t * dst) | ||||
| { | ||||
| 	return cw_put_local_ip_address(conn->sock,dst,CAPWAP_ELEM_WTP_IPV4_IP_ADDRESS,CAPWAP_ELEM_WTP_IPV6_IP_ADDRESS); | ||||
| } | ||||
| */ | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user