Compare commits
	
		
			48 Commits
		
	
	
		
			master
			...
			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 | Open Source CAPWAP WLC + WTP | ||||||
|  |  | ||||||
| Current status: early development. | Current status: development. | ||||||
|  |  | ||||||
| See also http://7u83.cauwersin.com/?cat=28 | 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\ | 	discovery_cache.o\ | ||||||
| 	rpc.o\ | 	rpc.o\ | ||||||
| 	statemachine.o\ | 	statemachine.o\ | ||||||
|  | 	hapd.o | ||||||
|  |  | ||||||
| ACTOBJS = \ | ACTOBJS = \ | ||||||
| 	act.o  | 	act.o  | ||||||
| @ -26,11 +27,17 @@ LIBS+=-lnettle | |||||||
| LIBS+=-lssl | LIBS+=-lssl | ||||||
| LIBS+=-lcrypto | LIBS+=-lcrypto | ||||||
| LIBS+=-ledit | 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 -DWITH_OPENSSL -DSYS_ARCH="$(ARCH)" -DSYS_ARCH="XXX" | ||||||
| FLAGS=-DWITH_IPV6 -DUSE_OPENSSL -DSYS_ARCH='"$(KERNEL)/$(ARCH)"' | 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 | ||||||
|  |  | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
| @ -43,8 +50,9 @@ all: $(PRG) $(ACTPRG) | |||||||
| $(PRG): $(OBJS)  | $(PRG): $(OBJS)  | ||||||
| 	$(CC) $(OBJS) -o $(PRG) $(LIBPATH) $(LDFLAGS) $(LIBS)  | 	$(CC) $(OBJS) -o $(PRG) $(LIBPATH) $(LDFLAGS) $(LIBS)  | ||||||
|  |  | ||||||
| $(ACTPRG): $(ACTOBJS) | #$(ACTPRG): $(ACTOBJS) | ||||||
| 	$(CC) $(ACTOBJS) -o $(ACTPRG) $(LIBPATH) $(LDFLAGS) $(LIBS) -ledit  | #	$(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 start_rpc(cw_Cfg_t *global_cfg); | ||||||
| int test_shell(); | int test_shell(); | ||||||
|  |  | ||||||
|  | void hapd_run(); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | |||||||
| @ -125,9 +125,20 @@ static int parse_args (int argc, char *argv[], struct bootcfg * bootcfg) | |||||||
| 				exit(EXIT_FAILURE); | 				exit(EXIT_FAILURE); | ||||||
| 			default: | 			default: | ||||||
| 			case 'h':  | 			case 'h':  | ||||||
| 				printf("%s: -vcmh\n",argv[0]); | 			{ | ||||||
|  | 				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); | 				exit(EXIT_SUCCESS); | ||||||
| 				break; | 				break; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -200,6 +211,7 @@ return 0; | |||||||
| */ | */ | ||||||
|  |  | ||||||
| static cw_Cfg_t * global_cfg = NULL; | 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[]) | int main (int argc, char *argv[]) | ||||||
| @ -225,6 +237,12 @@ int main (int argc, char *argv[]) | |||||||
| 		goto errX; | 		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"; | 	cw_log_name = "AC-Tube"; | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @ -440,7 +458,7 @@ int ac_run(cw_Cfg_t * cfg) | |||||||
| 				                        (struct sockaddr *) &srcaddr, | 				                        (struct sockaddr *) &srcaddr, | ||||||
| 				                        &srcaddrlen); | 				                        &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, | 				                        (struct sockaddr *) &srcaddr, | ||||||
| 				                        &srcaddrlen); | 				                        &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) | void process_cw_data_packet (int index, struct sockaddr *addr, uint8_t * buffer, int len) | ||||||
| { | { | ||||||
| 	char sock_buf[SOCK_ADDR_BUFSIZE]; | 	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(); | 	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); | 	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) { | 	if (!dm) { | ||||||
| 		cw_dbg (DBG_INFO, "No dataman %s,%d", sock_addr2str_p (addr, sock_buf), socklist[index].data_sockfd); | 		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_list_add (dm); | ||||||
| 		 |  | ||||||
| 		dataman_start (dm); | 		dataman_start (dm); | ||||||
| 		 |  | ||||||
| 		 |  | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	dataman_list_unlock(); | 	dataman_list_unlock(); | ||||||
| 	 | 	 | ||||||
| 	//dataman_add_packet (dm, buffer, len); | 	dataman_add_packet (dm, buffer, len); | ||||||
| 	 | 	 | ||||||
| 	return; | 	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]; | 	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 (!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); | 		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); | 		wtpman_start (wtpman, preamble & 0xf); | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	//printf("Got Packet with len: %d\n",len); | 	if(!dta) | ||||||
|  | 		wtpman_addpacket (wtpman, buffer, len); | ||||||
| 	wtpman_addpacket (wtpman, buffer, len); | 	else{ | ||||||
|  | //		cw_dbg(DBG_X,"Data packet received"); | ||||||
|  | 		wtpman_datapacket (wtpman, buffer, len); | ||||||
|  | 	} | ||||||
| 	wtplist_unlock(); | 	wtplist_unlock(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -631,7 +653,7 @@ void process_ctrl_packet (int index, struct sockaddr *addr, uint8_t * buffer, in | |||||||
| { | { | ||||||
| 	switch (socklist[index].ac_proto) { | 	switch (socklist[index].ac_proto) { | ||||||
| 		case AC_PROTO_CAPWAP: | 		case AC_PROTO_CAPWAP: | ||||||
| 			process_cw_ctrl_packet (index, addr, buffer, len); | //			process_cw_ctrl_packet (index, addr, buffer, len); | ||||||
| 			return; | 			return; | ||||||
| 			 | 			 | ||||||
| 		/*case AC_PROTO_LWAPP: | 		/*case AC_PROTO_LWAPP: | ||||||
|  | |||||||
| @ -15,10 +15,18 @@ capwap/ssl-dhbits: 1024 | |||||||
| capwap/ssl-keyfile:  "../../ssl/intermediate-ca/int-ca.key" | capwap/ssl-keyfile:  "../../ssl/intermediate-ca/int-ca.key" | ||||||
| capwap/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt" | capwap/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt" | ||||||
|  |  | ||||||
| cisco/ssl-keyfile:  "../../ssl/intermediate-ca/int-ca.key" | #mod/cisco/ssl-keyfile:  "../../ssl/intermediate-ca/int-ca.key" | ||||||
| cisco/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt" | #mod/cisco/ssl-certfile: "../../ssl/intermediate-ca/int-ca.crt" | ||||||
| cisco/ssl-cipher: DEFAULT | # | ||||||
| cisco/ssl-dhbits: 2048 | 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: unix:/tmp/actube | ||||||
| actube/rpc/listen: tcp:127.0.0.1:5000 | actube/rpc/listen: tcp:127.0.0.1:5000 | ||||||
| actube/rpc/enable: true | 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/dtls-policy:  1 | ||||||
| capwap/ac-descriptor/hardware/vendor: 4232704 | capwap/ac-descriptor/hardware/vendor: 4232704 | ||||||
| @ -59,17 +75,100 @@ capwap/ac-descriptor/station-limit: 1000 | |||||||
| capwap/ac-descriptor/stations: 0 | 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 | ||||||
| # | # | ||||||
| capwap/timers/change-state-pending-timer: Word: 3 | capwap/timers/change-state-pending-timer: 3 | ||||||
| capwap/timers/data-check-timer: Word: 10 | capwap/timers/data-check-timer: 10 | ||||||
| capwap/timers/echo-interval :Byte: 30 | capwap/timers/echo-interval: 30 | ||||||
| capwap/timers/max-discovery-interval :Byte: 10 | 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/timer.h" | ||||||
| #include "cw/cw.h" | #include "cw/cw.h" | ||||||
| #include "cw/format.h" | #include "cw/format.h" | ||||||
| #include "cw/netconn.h" | #include "cw/conn.h" | ||||||
|  |  | ||||||
| #include "cw/log.h" | #include "cw/log.h" | ||||||
| #include "cw/dbg.h" | #include "cw/dbg.h" | ||||||
|  | #include "cw/file.h" | ||||||
|  | #include "cw/dot11.h" | ||||||
|  |  | ||||||
| #include "wtplist.h" | #include "wtplist.h" | ||||||
| #include "dataman.h" | #include "dataman.h" | ||||||
| @ -19,8 +21,8 @@ pthread_mutex_t dataman_list_mutex; | |||||||
|  |  | ||||||
| static int cmp(const void *d1, const void *d2) | static int cmp(const void *d1, const void *d2) | ||||||
| { | { | ||||||
| 	struct netconn *nc1 = ((struct dataman *) d1)->nc; | 	struct cw_Conn *nc1 = ((struct dataman *) d1)->nc; | ||||||
| 	struct netconn *nc2 = ((struct dataman *) d1)->nc; | 	struct cw_Conn *nc2 = ((struct dataman *) d1)->nc; | ||||||
|  |  | ||||||
| 	int r = nc1->sock - nc2->sock; | 	int r = nc1->sock - nc2->sock; | ||||||
| 	if (r != 0) | 	if (r != 0) | ||||||
| @ -52,7 +54,7 @@ void dataman_destroy(struct dataman *dm) | |||||||
| { | { | ||||||
| 	if (!dm) | 	if (!dm) | ||||||
| 		return; | 		return; | ||||||
| 	netconn_destroy(dm->nc); | 	conn_destroy(dm->nc); | ||||||
| } | } | ||||||
|  |  | ||||||
| struct dataman *dataman_create(int sock, struct sockaddr *addr) | 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)); | 	struct dataman *dm = malloc(sizeof(struct dataman)); | ||||||
| 	if (!dm) | 	if (!dm) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | 	memset(dm,0,sizeof(struct dataman)); | ||||||
| 	dm->nc = netconn_create(sock, addr, 100); | 	dm->nc = cw_conn_create(sock, addr, 100); | ||||||
| 	return dm; | 	return dm; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| struct dataman *dataman_list_get(int sock, struct sockaddr *addr) | struct dataman *dataman_list_get(int sock, struct sockaddr *addr) | ||||||
| { | { | ||||||
| 	struct netconn search_nc; | 	struct cw_Conn search_nc; | ||||||
| 	struct dataman search_dm; | 	struct dataman search_dm; | ||||||
|  |  | ||||||
| 	search_nc.sock = sock; | 	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); | 	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; | 	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); | 	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("len len %d\n",l); | ||||||
| 				printf("Total len = %d\n",total_len); | 				printf("Total len = %d\n",total_len); | ||||||
|  |  | ||||||
| 				netconn_send_capwap_msg(nc,buffer,total_len); | 				cw_send_msg(nc,buffer,total_len); | ||||||
| 				return len; | 				return len; | ||||||
| 					 | 					 | ||||||
|  |  | ||||||
| @ -167,26 +169,107 @@ int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len) | |||||||
| 	return -1;	 | 	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) | 			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 */ | 	/* The very first data message MUST be a keep-alive message */ | ||||||
| 	if (!cw_get_hdr_flag_k(rawmsg)){ | 	if (!cw_get_hdr_flag_k(rawmsg)){ | ||||||
|  |  | ||||||
|  | //		cw_dbg(DBG_X,"No K Flag founde"); | ||||||
| 		errno = EAGAIN; | 		errno = EAGAIN; | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | //	cw_dbg(DBG_X, "Goto Keep Alive Pack"); | ||||||
| 	return dataman_process_keep_alive(nc,rawmsg,len); | 	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) | 			struct sockaddr *from) | ||||||
| { | { | ||||||
| 	if (cw_get_hdr_flag_k(rawmsg)){ | 	if (cw_get_hdr_flag_k(rawmsg)){ | ||||||
| 		return dataman_process_keep_alive(nc,rawmsg,len); | 		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"); | 	cw_dbg(DBG_X,"There was someting else than dataman"); | ||||||
|  |  | ||||||
| 	return 1; | 	return 1; | ||||||
|  |  | ||||||
| } | } | ||||||
| @ -195,12 +278,22 @@ void dataman_run(struct dataman *dm) | |||||||
| { | { | ||||||
| 	time_t timer = cw_timer_start(2); | 	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->process_message=dataman_process_message0; | ||||||
| 	dm->nc->data = dm; | 	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)){ | 	while (!cw_timer_timeout(timer)){ | ||||||
| 		netconn_read_messages(dm->nc); | 		cw_read_messages(dm->nc); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (!dm->wtpman){ | 	if (!dm->wtpman){ | ||||||
| @ -215,7 +308,7 @@ void dataman_run(struct dataman *dm) | |||||||
| 	while (1){ | 	while (1){ | ||||||
| 		time_t timer = cw_timer_start(2); | 		time_t timer = cw_timer_start(2); | ||||||
| 		while (!cw_timer_timeout(timer)){ | 		while (!cw_timer_timeout(timer)){ | ||||||
| 			netconn_read_messages(dm->nc); | 			cw_read_messages(dm->nc); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -3,12 +3,11 @@ | |||||||
|  |  | ||||||
| #include <pthread.h> | #include <pthread.h> | ||||||
|  |  | ||||||
| /*#include "cw/netconn.h"*/ |  | ||||||
|  |  | ||||||
| #include "wtpman.h" | #include "wtpman.h" | ||||||
|  |  | ||||||
| struct dataman { | struct dataman { | ||||||
| 	struct netconn *nc; | 	struct cw_Conn *nc; | ||||||
| 	pthread_t thread; | 	pthread_t thread; | ||||||
| 	struct wtpman * wtpman; | 	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_lock() pthread_mutex_lock(&dataman_list_mutex) | ||||||
| #define dataman_list_unlock() pthread_mutex_unlock(&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 | #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 | ||||||
|  |  | ||||||
							
								
								
									
										366
									
								
								src/ac/rpc.c
									
									
									
									
									
								
							
							
						
						
									
										366
									
								
								src/ac/rpc.c
									
									
									
									
									
								
							| @ -2,6 +2,7 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <ctype.h> | ||||||
|  |  | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||||
| @ -16,6 +17,7 @@ | |||||||
| #include "cw/log.h" | #include "cw/log.h" | ||||||
| #include "cw/dbg.h" | #include "cw/dbg.h" | ||||||
|  |  | ||||||
|  | #include "wtpman.h" | ||||||
|  |  | ||||||
| #include "cw/connlist.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 exit_cmd(struct rpcdata *sd, const char * cmd); | ||||||
| int prompt_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 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); | //void show_cfg (FILE *out, mavl_t ktv); | ||||||
| int show_aps (FILE *out); | int show_aps (FILE *out); | ||||||
| @ -88,6 +95,11 @@ static struct command cmdlist[]={ | |||||||
| 	{"set", set_cmd }, | 	{"set", set_cmd }, | ||||||
| 	{"wlan0",wlan0_cmd}, | 	{"wlan0",wlan0_cmd}, | ||||||
| 	{"global_cfg", global_cfg_cmd}, | 	{"global_cfg", global_cfg_cmd}, | ||||||
|  | 	{"status",status_cmd}, | ||||||
|  | 	{"clear",clear_cmd}, | ||||||
|  | 	{"load",load_cmd}, | ||||||
|  | 	{"save",save_cmd}, | ||||||
|  |  | ||||||
|  |  | ||||||
| 	{"@prompt",prompt_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); | 	finish_cmd(sd->out); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| @ -138,10 +159,6 @@ int list_cmd(struct rpcdata *sd, const char *cmd) | |||||||
|  |  | ||||||
| int exit_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); | 	finish_cmd(sd->out); | ||||||
| 	fflush(sd->out); | 	fflush(sd->out); | ||||||
| 	return 1; | 	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; | 	struct cw_Conn * conn; | ||||||
| 	wtplist_lock(); | 	wtplist_lock(); | ||||||
| 	conn = find_ap(sd->prompt); | 	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); | 		fprintf(sd->out,"WTP '%s' not found\n",sd->prompt); | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		cw_cfg_fdump(sd->out,conn->remote_cfg); | 		cw_cfg_fdump(sd->out,conn->remote_cfg,str); | ||||||
| 	} | 	} | ||||||
| 	finish_cmd(sd->out); | 	finish_cmd(sd->out); | ||||||
| 	wtplist_unlock(); | 	wtplist_unlock(); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ucfg_cmd(struct rpcdata *sd, const char *cmd) |  | ||||||
|  | int status_cmd(struct rpcdata *sd, const char *cmd) | ||||||
| { | { | ||||||
| //	struct cw_Conn * conn; | 	struct cw_Conn * conn; | ||||||
| 	stop(); | 	int i; | ||||||
| //	show_cfg(sd->out,sd->update_cfg); | 	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; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| #include "wtpman.h" |  | ||||||
|  |  | ||||||
| int | int | ||||||
| send_cmd(struct rpcdata * sd, const char *cmd) | send_cmd(struct rpcdata * sd, const char *cmd) | ||||||
| { | { | ||||||
|  | 	struct wtpman * wtpman; | ||||||
| 	struct cw_Conn * conn; | 	struct cw_Conn * conn; | ||||||
| 	wtplist_lock(); | 	wtplist_lock(); | ||||||
| 	conn = find_ap(sd->prompt); | 	conn = find_ap(sd->prompt); | ||||||
| 	if (conn==NULL){ | 	if (conn==NULL){ | ||||||
| 		fprintf(sd->out,"WTP '%s' not found\n",sd->prompt); | 		fprintf(sd->out,"WTP '%s' not found\n",sd->prompt); | ||||||
|  | 		goto errX; | ||||||
| 	} | 	} | ||||||
| 	else { | 	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(); | 	wtplist_unlock(); | ||||||
|  | 	finish_cmd(sd->out); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -205,8 +306,6 @@ wlan0_cmd(struct rpcdata * sd, const char *cmd) | |||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		FILE *f=fopen("wlan0.ktv","r"); | 		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); | 		fclose(f); | ||||||
| 	} | 	} | ||||||
| 	wtplist_unlock(); | 	wtplist_unlock(); | ||||||
| @ -217,60 +316,76 @@ int set_cmd(struct rpcdata *sd, const char *str) | |||||||
| { | { | ||||||
|  |  | ||||||
| 	cw_Cfg_t *cfg; | 	cw_Cfg_t *cfg; | ||||||
|  |  | ||||||
| 	cfg = cw_cfg_create(); | 	cfg = cw_cfg_create(); | ||||||
|  |  | ||||||
| 	cw_cfg_read_from_string(str,cfg); | 	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); | 	cw_cfg_destroy(cfg); | ||||||
|  |  | ||||||
| 	finish_cmd(sd->out); | 	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; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int del_cmd(struct rpcdata *sd, const char *str) | int load_cmd(struct rpcdata *sd, const char *str) | ||||||
| { | { | ||||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | 	char fn[CW_CFG_MAX_KEY_LEN]; | ||||||
| 	sscanf(str,"%s",key); | 	int rc; | ||||||
| 	stop(); | 	const char * dir=cw_cfg_get(sd->global_cfg,"actube/rpc/macros-dir","./rpc-macros"); | ||||||
| //	cw_ktv_del_sub(sd->update_cfg,key); |  | ||||||
| // |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | 	sprintf(fn,"%s/%s.ckv",dir,str); | ||||||
|  | 	rc= cw_cfg_load(fn,sd->update_cfg); | ||||||
|  |  | ||||||
| /* | 	if (rc){ | ||||||
| void show_cfg (FILE *out, mavl_t ktv) | 		fprintf(sd->out,"Error loading %s: %s\n",fn,strerror(rc)); | ||||||
| { |  | ||||||
| 	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); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	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 *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 print_mw(FILE *f, int w, const char * str) | void print_mw(FILE *f, int w, const char * str) | ||||||
| @ -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 * find_cmd(const char *cmd) | ||||||
| { | { | ||||||
| 	struct command * search,*result; | 	struct command * search,*result; | ||||||
| @ -438,7 +497,6 @@ int execute_cmd (struct rpcdata * sd, const char *str) | |||||||
| 	char cmd[1024]; | 	char cmd[1024]; | ||||||
| 	char args[1024]; | 	char args[1024]; | ||||||
| 	int n; | 	int n; | ||||||
| 	struct cw_Val_Reader reader; |  | ||||||
| 	struct command * searchcmd; | 	struct command * searchcmd; | ||||||
|  |  | ||||||
| 	args[0]=0; | 	args[0]=0; | ||||||
| @ -450,7 +508,19 @@ int execute_cmd (struct rpcdata * sd, const char *str) | |||||||
| 	searchcmd = find_cmd(cmd); | 	searchcmd = find_cmd(cmd); | ||||||
| 	if (searchcmd!=NULL){ | 	if (searchcmd!=NULL){ | ||||||
| 		if (searchcmd->fun != 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{ | 	else{ | ||||||
| @ -460,73 +530,8 @@ int execute_cmd (struct rpcdata * sd, const char *str) | |||||||
|  |  | ||||||
| 	return 0; | 	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) | 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.in = file; | ||||||
| 	sd.out = file;	 | 	sd.out = file;	 | ||||||
| 	sd.global_cfg=global_cfg; | 	sd.global_cfg=global_cfg; | ||||||
|  | 	sd.update_cfg=cw_cfg_create(); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	sprintf(sd.prompt,"%s","*"); | 	sprintf(sd.prompt,"%s","*"); | ||||||
| @ -591,9 +597,6 @@ void * run_rpc_server (void * arg) | |||||||
| 			close (clientsock); | 			close (clientsock); | ||||||
| 		} | 		} | ||||||
| 		 | 		 | ||||||
| 		 |  | ||||||
| 		 |  | ||||||
| 		//cw_dbg (DBG_INFO,"Accepting shell session %i, %s", rc, strerror (errno)); |  | ||||||
| 	}	 | 	}	 | ||||||
| 	 | 	 | ||||||
| 	return NULL; | 	return NULL; | ||||||
| @ -633,8 +636,6 @@ int create_tcp_fd(const char *name) | |||||||
| } | } | ||||||
| static int create_unix_fd(const char *name) | static int create_unix_fd(const char *name) | ||||||
| { | { | ||||||
|         //struct sockaddr_storage client; |  | ||||||
| 	//socklen_t client_size; |  | ||||||
| 	struct sockaddr_un addr; | 	struct sockaddr_un addr; | ||||||
| 	int rc,fd; | 	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)); | 		cw_log (LOG_ERR, "Can't bind socket 'unix:%s', %s", name, strerror (errno)); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 	//int clientsock = accept (fd, (struct sockaddr*) &client, &client_size); |  | ||||||
|  |  | ||||||
| 	return fd; | 	return fd; | ||||||
| } | } | ||||||
| @ -657,7 +657,7 @@ int start_rpc(cw_Cfg_t *global_cfg) | |||||||
| { | { | ||||||
| 	struct sockdata * sockdata; | 	struct sockdata * sockdata; | ||||||
| 	const char *sockname; | 	const char *sockname; | ||||||
| 	int rc; //, type; | 	int rc;  | ||||||
| 	int fd; | 	int fd; | ||||||
|  |  | ||||||
| 	rc = cw_cfg_get_bool(global_cfg,"actube/rpc/enable",1); | 	rc = cw_cfg_get_bool(global_cfg,"actube/rpc/enable",1); | ||||||
|  | |||||||
							
								
								
									
										318
									
								
								src/ac/wtpman.c
									
									
									
									
									
								
							
							
						
						
									
										318
									
								
								src/ac/wtpman.c
									
									
									
									
									
								
							| @ -44,6 +44,8 @@ | |||||||
|  |  | ||||||
| #include "actube.h" | #include "actube.h" | ||||||
|  |  | ||||||
|  | #include "cw/dot11.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| static void wtpman_remove(struct wtpman *wtpman) | 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)*/ | /*#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) | static void *wtpman_main(void *arg) | ||||||
| { | { | ||||||
| 	//mavl_t r; | 	//mavl_t r; | ||||||
| @ -343,6 +398,7 @@ static void *wtpman_main(void *arg) | |||||||
| 	conn->capwap_prevstate = CAPWAP_STATE_DTLS_SETUP; | 	conn->capwap_prevstate = CAPWAP_STATE_DTLS_SETUP; | ||||||
| 	conn->capwap_state = CAPWAP_STATE_JOIN; | 	conn->capwap_state = CAPWAP_STATE_JOIN; | ||||||
| 	rc = 0; | 	rc = 0; | ||||||
|  | 	wtpman->update=0; | ||||||
|  |  | ||||||
| 	while (1) { | 	while (1) { | ||||||
|  |  | ||||||
| @ -359,59 +415,25 @@ static void *wtpman_main(void *arg) | |||||||
|  |  | ||||||
|  |  | ||||||
| 		while (!cw_timer_timeout(timer)) { | 		while (!cw_timer_timeout(timer)) { | ||||||
|  | 			rc = run_update(wtpman); | ||||||
|  | 			if (rc !=EAGAIN) | ||||||
|  | 				break; | ||||||
|  |  | ||||||
| 			rc = cw_read_messages(wtpman->conn); | 			rc = cw_read_messages(wtpman->conn); | ||||||
|  | 			 | ||||||
| 			if (rc < 0) { | 			if (rc < 0) { | ||||||
| 				if (errno == EAGAIN) | 				if (errno == EAGAIN){ | ||||||
| 					continue; | 					continue; | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (rc < 0) { | 		if (rc < 0) { | ||||||
| 			conn->capwap_prevstate = conn->capwap_state; | 			conn->capwap_prevstate = conn->capwap_state; | ||||||
| 			conn->capwap_state = CAPWAP_STATE_TIMEOUT; | 			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); | 	exit(0); | ||||||
|  |  | ||||||
| 	return NULL; | 	return NULL; | ||||||
| @ -433,72 +455,114 @@ void wtpman_destroy(struct wtpman *wtpman) | |||||||
|  |  | ||||||
| static void copy(struct cw_ElemHandlerParams * params) | 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_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]; | 	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"); | 	cw_dbg(DBG_X,"DISCOVERY Callback"); | ||||||
| 	copy(params); | 	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); | 	cw_cfg_clear(params->cfg); | ||||||
|  | 	if (d->parent) | ||||||
|  | 		return d->parent->fun(params,d->parent); | ||||||
|  |  | ||||||
| 	return 0; | 	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; | 	catch_cfg(params,0,"\n#\n# Join Request\n#\n"); | ||||||
| 	char filename[200]; | 	if (d->parent) | ||||||
|  | 		return d->parent->fun(params,d->parent); | ||||||
| 	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); |  | ||||||
| 	return 0; | 	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; | 	struct cw_Cfg_iter cfi; | ||||||
| 	char filename[200]; | 	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); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | */ | ||||||
|  |  | ||||||
| 	cw_dbg(DBG_X,"UPDATE Callback"); | static int cfg_status_cb(struct cw_ElemHandlerParams * params, struct cw_MsgCb_data *d) | ||||||
| 	copy(params); | { | ||||||
|  | 	catch_cfg(params,0,"\n#\n# Configuration Status Request\n#\n"); | ||||||
| 	const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default"); | 	if (d->parent) | ||||||
| 	sprintf(filename,"wtp-status-%s.ckv",wtpname); | 		return d->parent->fun(params,d->parent); | ||||||
| 	cw_cfg_save(filename,params->cfg,NULL); |  | ||||||
| //stop();	 |  | ||||||
| 	return 0; | 	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 cw_Conn * conn = (struct cw_Conn*)params->conn; | ||||||
|  | 	struct wtpman * wtpman = (struct wtpman *)conn->data; | ||||||
|  |  | ||||||
| 	char filename[200]; | 	char filename[200]; | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -507,9 +571,26 @@ static int event_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, i | |||||||
| 	copy(params); | 	copy(params); | ||||||
|  |  | ||||||
| 	const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default"); | 	const char * wtpname = cw_cfg_get(conn->remote_cfg,"capwap/wtp-name","default"); | ||||||
| 	sprintf(filename,"wtp-event-%s.ckv",wtpname); | 	sprintf(filename,"wtp-event-%d-%s.ckv",wtpman->ctr++,wtpname); | ||||||
| 	cw_cfg_save(filename,conn->remote_cfg,NULL); | 	cw_cfg_save(filename,params->cfg,NULL); | ||||||
| //stop();	 | 	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; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -522,7 +603,7 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | |||||||
| { | { | ||||||
| 	struct sockaddr dbgaddr; | 	struct sockaddr dbgaddr; | ||||||
| 	socklen_t dbgaddrl; | 	socklen_t dbgaddrl; | ||||||
| 	int sockfd, replyfd; | 	int sockfd, replyfd, data_sockfd,data_replyfd; | ||||||
| 	char sock_buf[SOCK_ADDR_BUFSIZE]; | 	char sock_buf[SOCK_ADDR_BUFSIZE]; | ||||||
|  |  | ||||||
| 	struct wtpman *wtpman; | 	struct wtpman *wtpman; | ||||||
| @ -530,10 +611,13 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | |||||||
| 	if (!wtpman) | 	if (!wtpman) | ||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
|  | 	wtpman->ctr=0; | ||||||
|  |  | ||||||
| 	if (socklist[socklistindex].type != SOCKLIST_UNICAST_SOCKET) { | 	if (socklist[socklistindex].type != SOCKLIST_UNICAST_SOCKET) { | ||||||
|  |  | ||||||
| 		int port = sock_getport(&socklist[socklistindex].addr); | 		int port = sock_getport(&socklist[socklistindex].addr); | ||||||
| 		replyfd = socklist_find_reply_socket(srcaddr, port); | 		replyfd = socklist_find_reply_socket(srcaddr, port); | ||||||
|  | 		data_replyfd=replyfd; | ||||||
|  |  | ||||||
| 		if (replyfd == -1) { | 		if (replyfd == -1) { | ||||||
| 			cw_log(LOG_ERR, | 			cw_log(LOG_ERR, | ||||||
| @ -544,10 +628,11 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | |||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		replyfd = socklist[socklistindex].sockfd; | 		replyfd = socklist[socklistindex].sockfd; | ||||||
|  | 		data_replyfd = socklist[socklistindex].data_sockfd; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	sockfd = replyfd;	/*//socklist[socklistindex].reply_sockfd; */ | 	sockfd = replyfd;	/*//socklist[socklistindex].reply_sockfd; */ | ||||||
|  | 	data_sockfd = data_replyfd; | ||||||
|  |  | ||||||
| 	dbgaddrl = sizeof(dbgaddr); | 	dbgaddrl = sizeof(dbgaddr); | ||||||
| 	getsockname(sockfd, &dbgaddr, &dbgaddrl); | 	getsockname(sockfd, &dbgaddr, &dbgaddrl); | ||||||
| @ -565,6 +650,21 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | |||||||
| 		wtpman_destroy(wtpman); | 		wtpman_destroy(wtpman); | ||||||
| 		return NULL; | 		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->global_cfg = global_cfg; | ||||||
| 	wtpman->conn->local_cfg = cw_cfg_create(); | 	wtpman->conn->local_cfg = cw_cfg_create(); | ||||||
| 	wtpman->wtp_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->role = CW_ROLE_AC; | ||||||
| 	wtpman->conn->data=wtpman; | 	wtpman->conn->data=wtpman; | ||||||
|  | 	wtpman->dconn->data=wtpman; | ||||||
|  |  | ||||||
| 	wtpman->conn->cfg_list[0]=wtpman->conn->update_cfg; | 	wtpman->conn->cfg_list[0]=wtpman->conn->update_cfg; | ||||||
| 	wtpman->conn->cfg_list[1]=wtpman->conn->remote_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, | 	sock_copyaddr(&wtpman->conn->data_addr, | ||||||
| 		      (struct sockaddr *) &wtpman->conn->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; | //	wtpman->conn->mods = conf_mods; | ||||||
| @ -634,15 +718,37 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, | |||||||
| 			       cmod->name, bmod->name); | 			       cmod->name, bmod->name); | ||||||
| 			wtpman->conn->msgset = | 			wtpman->conn->msgset = | ||||||
| 			    cw_mod_get_msg_set(wtpman->conn, cmod, bmod); | 			    cw_mod_get_msg_set(wtpman->conn, cmod, bmod); | ||||||
|  |  | ||||||
|  | 			wtpman->dconn->msgset=wtpman->conn->msgset; | ||||||
| 			wtpman->conn->detected = 1; | 			wtpman->conn->detected = 1; | ||||||
| 			cmod->setup_cfg(wtpman->conn); | 			cmod->setup_cfg(wtpman->conn); | ||||||
| //	               if (wtpman->conn->setup_complete) | //	               if (wtpman->conn->setup_complete) | ||||||
| //        	                wtpman->conn->setup_complete(wtpman->conn); | //        	                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); | 	cw_dbg(DBG_X,"WTPMAN_CREATED: %p",wtpman); | ||||||
|  |  | ||||||
| 	return 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) | 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); | 	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); | 	cw_dbg(DBG_INFO, "Starting wtpman, DTLS mode = %d", dtlsmode); | ||||||
| 	wtpman->dtlsmode = dtlsmode; | 	wtpman->dtlsmode = dtlsmode; | ||||||
| 	pthread_create(&wtpman->thread, NULL, wtpman_main, (void *) wtpman); | 	pthread_create(&wtpman->thread, NULL, wtpman_main, (void *) wtpman); | ||||||
|  | 	pthread_create(&wtpman->thread, NULL, wtpman_data_main, (void *) wtpman); | ||||||
| 	return; | 	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; | 	pthread_t thread; | ||||||
|  |  | ||||||
| 	struct cw_Conn *conn; | 	struct cw_Conn *conn; | ||||||
|  | 	struct cw_Conn *dconn; | ||||||
|  |  | ||||||
|  |  | ||||||
| 	/* wtp data */ | 	/* wtp data */ | ||||||
| @ -40,8 +41,13 @@ struct wtpman { | |||||||
|  |  | ||||||
| 	cw_Cfg_t * wtp_cfg; | 	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_addpacket(struct wtpman *wtpman, uint8_t * packet, int len); | ||||||
| extern void wtpman_destroy(struct wtpman *wtpman); | extern void wtpman_destroy(struct wtpman *wtpman); | ||||||
| extern void wtpman_start(struct wtpman *wtpman, int dtlsmode); | 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.c\ | ||||||
| 	cw_check_missing_mand.c\ | 	cw_check_missing_mand.c\ | ||||||
| 	cw_clock_lap.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_filename.c\ | ||||||
| 	cw_format_dump.c\ | 	cw_format_dump.c\ | ||||||
| 	cw_format_pkt_hdr.c\ | 	cw_format_pkt_hdr.c\ | ||||||
| @ -18,13 +15,11 @@ CWSRC=\ | |||||||
| 	cw_in_capwap_local_ipv4_address.c\ | 	cw_in_capwap_local_ipv4_address.c\ | ||||||
| 	cw_in_capwap_local_ipv6_address.c\ | 	cw_in_capwap_local_ipv6_address.c\ | ||||||
| 	cw_in_generic_with_index.c\ | 	cw_in_generic_with_index.c\ | ||||||
| 	cw_in_radio_generic_struct.c\ |  | ||||||
| 	cw_in_idx_generic.c\ | 	cw_in_idx_generic.c\ | ||||||
| 	cw_in_idx_generic_struct.c\ | 	cw_in_idx_generic_struct.c\ | ||||||
| 	cw_in_generic_indexed_enum.c\ | 	cw_in_generic_indexed_enum.c\ | ||||||
| 	cw_out_generic_indexed_enum.c\ | 	cw_out_generic_indexed_enum.c\ | ||||||
| 	cw_in_generic_enum.c\ | 	cw_in_generic_enum.c\ | ||||||
| 	cw_out_generic_struct.c\ |  | ||||||
| 	cw_out_idx_generic_struct.c\ | 	cw_out_idx_generic_struct.c\ | ||||||
| 	cw_init_data_keep_alive_msg.c\ | 	cw_init_data_keep_alive_msg.c\ | ||||||
| 	cw_inline.c\ | 	cw_inline.c\ | ||||||
| @ -37,7 +32,6 @@ CWSRC=\ | |||||||
| 	cw_put_elem_radio_operational_state.c\ | 	cw_put_elem_radio_operational_state.c\ | ||||||
| 	cw_put_image_data.c\ | 	cw_put_image_data.c\ | ||||||
| 	cw_put_local_ip_address.c\ | 	cw_put_local_ip_address.c\ | ||||||
| 	cw_radio_set_admin_state.c\ |  | ||||||
| 	cw_rand.c\ | 	cw_rand.c\ | ||||||
| 	cw_randint.c\ | 	cw_randint.c\ | ||||||
| 	cw_read_ac_descriptor.c\ | 	cw_read_ac_descriptor.c\ | ||||||
| @ -62,11 +56,12 @@ CWSRC=\ | |||||||
| 	cw_type_ipaddress.c\ | 	cw_type_ipaddress.c\ | ||||||
| 	cw_type_word.c\ | 	cw_type_word.c\ | ||||||
| 	cw_type_sysptr.c\ | 	cw_type_sysptr.c\ | ||||||
|  | 	cw_type_array.c\ | ||||||
|  | 	cw_type_bits.c\ | ||||||
| 	cw_write_descriptor_subelem.c\ | 	cw_write_descriptor_subelem.c\ | ||||||
| 	cw_write_radio_element.c\ | 	cw_write_radio_element.c\ | ||||||
| 	cw_detect_nat.c\ | 	cw_detect_nat.c\ | ||||||
| 	cw_read_from.c \ | 	cw_read_from.c \ | ||||||
| 	cw_in_generic_struct.c\ |  | ||||||
|  |  | ||||||
| #	cw_in_check_disc_req.c\ | #	cw_in_check_disc_req.c\ | ||||||
| #	cw_in_check_img_data_req_ac.c\ | #	cw_in_check_img_data_req_ac.c\ | ||||||
| @ -77,46 +72,16 @@ CWSRC=\ | |||||||
| #	cw_out_generic.c\ | #	cw_out_generic.c\ | ||||||
| #	 | #	 | ||||||
| #	cw_process_element.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=\ | KTVSRC=\ | ||||||
| 	cfg.c\ | 	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=\ | LWSRC=\ | ||||||
| 	lw_addelem.c\ | 	lw_addelem.c\ | ||||||
| 	lw_checksum.c\ | 	lw_checksum.c\ | ||||||
| @ -169,7 +134,8 @@ LOGSRC=\ | |||||||
| 	log_errno.c\ | 	log_errno.c\ | ||||||
| 	log_syslog.c\ | 	log_syslog.c\ | ||||||
| 	dbg.c\ | 	dbg.c\ | ||||||
| 	dbg_strings.c\ |  | ||||||
|  | #	dbg_strings.c\ | ||||||
|  |  | ||||||
| MISCSRC=\ | MISCSRC=\ | ||||||
| 	bstr16_create.c\ | 	bstr16_create.c\ | ||||||
| @ -205,7 +171,6 @@ MISCSRC=\ | |||||||
| 	msgset.c\ | 	msgset.c\ | ||||||
| 	send.c\ | 	send.c\ | ||||||
| 	strheap.c\ | 	strheap.c\ | ||||||
| 	netconn.c\ |  | ||||||
| 	conn.c \ | 	conn.c \ | ||||||
| 	val.c \ | 	val.c \ | ||||||
| 	discovery.c\ | 	discovery.c\ | ||||||
| @ -222,6 +187,7 @@ MISCSRC=\ | |||||||
| #	cw_put_msg.c\ | #	cw_put_msg.c\ | ||||||
| #	conn_process_packet.c\ | #	conn_process_packet.c\ | ||||||
| #	conn_destroy.c\ | #	conn_destroy.c\ | ||||||
|  | 	netconn.c\ | ||||||
|  |  | ||||||
| DTLSSRC+=\ | DTLSSRC+=\ | ||||||
| 	dtls_bio.c\ | 	dtls_bio.c\ | ||||||
|  | |||||||
| @ -465,9 +465,9 @@ enum cw_reboot_failure_types { | |||||||
| /**  | /**  | ||||||
|  * The Missing AC List Result Code is sent by the  |  * The Missing AC List Result Code is sent by the  | ||||||
|  * WTP to the AC when the AC List is missing */ |  * WTP to the AC when the AC List is missing */ | ||||||
| #define CW_RESULT_MISSING_AC_LIST				1 | #define CW_RESULT_MISSING_AC_LIST					1 | ||||||
| #define CAPWAP_RESULT_SUCCESS_NAT				2 | #define CAPWAP_RESULT_SUCCESS_NAT					2 | ||||||
| #define CW_RESULT_JOIN_FAILURE					3 | #define CAPWAP_RESULT_JOIN_FAILURE					3 | ||||||
| #define CW_RESULT_JOIN_RESOURCE_DEPLETION			4 | #define CW_RESULT_JOIN_RESOURCE_DEPLETION			4 | ||||||
| #define CW_RESULT_JOIN_UNKNOWN_SOURCE				5 | #define CW_RESULT_JOIN_UNKNOWN_SOURCE				5 | ||||||
| #define CW_RESULT_JOIN_INCORRECT_DATA				6 | #define CW_RESULT_JOIN_INCORRECT_DATA				6 | ||||||
| @ -491,7 +491,7 @@ enum cw_reboot_failure_types { | |||||||
|       13 Configuration Failure (Unable to Apply Requested Configuration |       13 Configuration Failure (Unable to Apply Requested Configuration | ||||||
|          - Service Not Provided) |          - 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) |  * 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 */ | /** IEEE 802.11 Antenna Message element */ | ||||||
| #define CAPWAP80211_ELEM_ANTENNA			1025 | #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); | 	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 *cw_cfg_create() | ||||||
| { | { | ||||||
| 	cw_Cfg_t * cfg; | 	cw_Cfg_t * cfg; | ||||||
| @ -88,6 +94,7 @@ cw_Cfg_t *cw_cfg_create() | |||||||
| 	if (cfg == NULL) | 	if (cfg == NULL) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	memset(cfg,0,sizeof(cw_Cfg_t)); | 	memset(cfg,0,sizeof(cw_Cfg_t)); | ||||||
|  | 	cfg->name = CW_CFG_DEFAULT_NAME; | ||||||
| 	cfg->cfg = mavl_create(cmp, del, sizeof(struct cw_Cfg_entry)); | 	cfg->cfg = mavl_create(cmp, del, sizeof(struct cw_Cfg_entry)); | ||||||
| 	if (cfg->cfg==NULL){ | 	if (cfg->cfg==NULL){ | ||||||
| 		cw_cfg_destroy(cfg); | 		cw_cfg_destroy(cfg); | ||||||
| @ -122,6 +129,16 @@ int cw_cfg_set(cw_Cfg_t * cfg, const char *key, const char *val) | |||||||
| 	return -1; | 	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) | const char *cw_cfg_get(cw_Cfg_t * cfg, const char *key, const char *def) | ||||||
| { | { | ||||||
| 	struct cw_Cfg_entry e, *r; | 	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; | 	int i; | ||||||
| 	struct cw_Cfg_entry e, *r; | 	struct cw_Cfg_entry e, *r; | ||||||
| 	for(i=0; cfg[i]!=NULL; i++){ | 	for(i=0; cfg[i]!=NULL; i++){ | ||||||
| //		cw_dbg(DBG_X,"GET_L IN: %p",cfg[i]); |  | ||||||
| 		e.key = key; | 		e.key = key; | ||||||
| 		r = mavl_get(cfg[i]->cfg, &e); | 		r = mavl_get(cfg[i]->cfg, &e); | ||||||
| 		if (r!=NULL) | 		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); | 	s = cw_cfg_get(cfg,key,def); | ||||||
| 	if(s==NULL) | 	if(s==NULL) | ||||||
|  | 		s=def; | ||||||
|  | 	if (s==NULL) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  |  | ||||||
| 	return bstr16_create_from_str(s); | 	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) | 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); | 	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; | 	mavliter_t it; | ||||||
| 	struct cw_Cfg_entry *e; | 	struct cw_Cfg_entry *e; | ||||||
| @ -194,6 +228,13 @@ void cw_cfg_fdump(FILE *f, cw_Cfg_t * cfg) | |||||||
| 	mavliter_foreach(&it) { | 	mavliter_foreach(&it) { | ||||||
|  |  | ||||||
| 		e = mavliter_get(&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); | 		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"); | 	FILE *f = fopen(filename, "rb"); | ||||||
| 	if (!f) | 	if (!f) | ||||||
| 		return errno; | 		return errno; | ||||||
|  | 	errno=0; | ||||||
| 	errs = cw_cfg_read_from_file(f, cfg); | 	errs = cw_cfg_read_from_file(f, cfg); | ||||||
| 	fclose(f); | 	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; | 	search.key = base; | ||||||
|  |  | ||||||
| 	mavliter_init(&(cfi->it), cfg->cfg); | 	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; | 	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; | 	struct cw_Cfg_entry *e; | ||||||
| 	int bl, kl; | 	int bl, kl; | ||||||
| 	const char *d; | //	const char *d; | ||||||
|  |  | ||||||
| 	e = mavliter_get(&(cfi->it)); | 	e = mavliter_get(&(cfi->it)); | ||||||
| 	if (e == NULL) | 	if (e == NULL){ | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 	if (cfi->base ==NULL) | ||||||
|  | 		goto eeX; | ||||||
|  |  | ||||||
| 	bl = strlen(cfi->base); | 	bl = strlen(cfi->base); | ||||||
| 	kl = strlen(e->key); | 	kl = strlen(e->key); | ||||||
|  |  | ||||||
| 	if (bl > kl) | 	if (bl > kl) | ||||||
| 		return NULL; | 		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; | 		return NULL; | ||||||
|  |  | ||||||
| 	if (d - e->key != bl) | /*	d = strchr(e->key, '.'); | ||||||
|  | 	if (d == NULL) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | 	if (d - e->key != bl) | ||||||
|  | 		return NULL;*/ | ||||||
|  |  | ||||||
| 	if (strncmp(cfi->base, e->key, bl) != 0) | 	if (strncmp(cfi->base, e->key, bl) != 0) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | eeX: | ||||||
| 	mavliter_next(&(cfi->it)); | 	mavliter_next(&(cfi->it)); | ||||||
| 	return e; | 	return e; | ||||||
| } | } | ||||||
| @ -615,7 +665,13 @@ int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, int def) | |||||||
| 	return v.val.boolean; | 	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) | uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def) | ||||||
| { | { | ||||||
| 	struct cw_Val v; | 	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; | 	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) | 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) | 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_new_index(cw_Cfg_t * cfg, const char *key) | ||||||
| int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key) |  | ||||||
| { | { | ||||||
| 	char ikey[CW_CFG_MAX_KEY_LEN]; | 	char ikey[CW_CFG_MAX_KEY_LEN]; | ||||||
| 	struct cw_Cfg_entry search, * result; | 	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; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	d = strchr(result->key,'.'); | 	d = strrchr(result->key,'.'); | ||||||
| 	if (d==NULL){ | 	if (d==NULL){ | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| @ -710,6 +772,46 @@ int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key) | |||||||
| 	return atoi(d+1)+1; | 	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) | 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; | 	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) | int cw_cfg_base_exists(cw_Cfg_t * cfg, const char *key) | ||||||
| { | { | ||||||
|         struct cw_Cfg_entry e, *result; |         struct cw_Cfg_entry e, *result; | ||||||
| //cw_dbg(DBG_X,"LOOX FOR: %s",key); | 	int rl,kl; | ||||||
|         e.key=key; | 	char skey[CW_CFG_MAX_KEY_LEN]; | ||||||
|         result = mavl_get_first(cfg->cfg,&e); | 	char * delimiters = "/."; | ||||||
|         if (result == NULL) | 	char * d; | ||||||
|                 return 0; |  | ||||||
| //cw_dbg(DBG_X,"BASEXXX: %s",result->key); |  | ||||||
|  |  | ||||||
| 	if (strlen(result->key)<strlen(key)) | 	/* can we find the base exactly ?*/ | ||||||
| 		return 0;		 | 	if (cw_cfg_get(cfg,key,NULL)!=NULL) | ||||||
| //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) |  | ||||||
| 		return 1; | 		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; | 	return 0; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										55
									
								
								src/cw/cfg.h
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								src/cw/cfg.h
									
									
									
									
									
								
							| @ -5,28 +5,53 @@ | |||||||
| #include "val.h" | #include "val.h" | ||||||
| #include "bstr.h" | #include "bstr.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  *@file | ||||||
|  |  *@brief | ||||||
|  |  *@defgroup CFG SOCK | ||||||
|  |  *@{ | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** Maximum size of a key used in cfg objects */ | ||||||
| #define CW_CFG_MAX_KEY_LEN 1024	 | #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 cw_Cfg { | ||||||
| 	struct mavl * cfg; | 	struct mavl * cfg;	/**< The AVL-tree containig the keys  | ||||||
| 	const char *name; | 				     and vals */ | ||||||
|  | 	const char *name;	/**< A name for this config object */ | ||||||
| 	int dbg_level; | 	int dbg_level; | ||||||
| 	const char *dbg_prefix; | 	const char *dbg_prefix; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef struct cw_Cfg cw_Cfg_t; | 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(); | cw_Cfg_t * cw_cfg_create(); | ||||||
| int cw_cfg_set(cw_Cfg_t *cfg,const char *key, const char *val); | int cw_cfg_set(cw_Cfg_t *cfg,const char *key, const char *val); | ||||||
| void cw_cfg_dump(cw_Cfg_t *cfg); | void cw_cfg_dump(cw_Cfg_t *cfg); | ||||||
| int cw_cfg_read_from_file(FILE * file, 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); | 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 cw_Cfg_iter{ | ||||||
| 	struct mavliter it; | 	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); | 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); | 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_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); | 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_copy(cw_Cfg_t *src, cw_Cfg_t *dst,int dbg_level,const char *dbg_prefix); | ||||||
| void cw_cfg_destroy(cw_Cfg_t *cfg); | 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, ...); | 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); | 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); | 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); | 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) \ | #define cw_cfg_get_word2(cfg1,cfg2,key,def) \ | ||||||
| 	cw_cfg_get_word(cfg1,key,cw_cfg_get_word(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 | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /**@}*/ | ||||||
|  |  | ||||||
|  | |||||||
| @ -24,11 +24,12 @@ | |||||||
|  |  | ||||||
| #include "dtls.h" | #include "dtls.h" | ||||||
|  |  | ||||||
|  | #define MAX_MSG_CBS 5 | ||||||
|  |  | ||||||
| struct msg_callback{ | struct msg_callback{ | ||||||
| 	int type; /**< message type */ | 	int type; 			/**< message type */ | ||||||
| 	cw_MsgCallbackFun fun; | 	struct cw_MsgCb_data data[MAX_MSG_CBS]; | ||||||
|  | 	int count; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| int msg_callback_cmp(const void *v1,const void *v2) | 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->remote_cfg = cw_cfg_create(); | ||||||
| 	conn->local_cfg = cw_cfg_create(); | 	conn->local_cfg = cw_cfg_create(); | ||||||
| 	conn->cfg_list[0]=NULL; | 	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; | 	int exists; | ||||||
|  |  | ||||||
| 	cb.type = type; | 	cb.type = type; | ||||||
| 	cb.fun = fun; | 	cb.data[0].fun = fun; | ||||||
| 	mavl_insert(conn->msg_callbacks,&cb,&exists); | 	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; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
| cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type) | cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type) | ||||||
| { | { | ||||||
| 	struct msg_callback cb,*result; | 	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) | 	if (result == NULL) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	return result->fun; | 	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 |  * Create a conn object | ||||||
|  * @param sock a socket |  * @param sock a socket | ||||||
| @ -106,8 +157,10 @@ struct cw_Conn * cw_conn_create(int sock, struct sockaddr * addr, int qsize) | |||||||
|  |  | ||||||
| 	conn->sock=sock; | 	conn->sock=sock; | ||||||
|  |  | ||||||
| 	if (addr) | 	if (addr){ | ||||||
| 		sock_copyaddr(&conn->addr,addr); | 		sock_copyaddr(&conn->addr,addr); | ||||||
|  | 		sock_addr2str_p(addr, conn->remote_addr);	 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	conn->fragman = fragman_create(); | 	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); | 		message->postprocess(¶ms,elems_ptr, elems_len); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type); | 	result_code = cw_conn_run_msg_cbs(conn,message->type,¶ms); | ||||||
| 	if (cb_fun != NULL){ |  | ||||||
| 		result_code = cb_fun(¶ms,elems_ptr, elems_len); | //	cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type); | ||||||
| 	} | 	if (result_code==-1){ | ||||||
| 	else{ |  | ||||||
| 		cw_cfg_clear(conn->update_cfg); | 		cw_cfg_clear(conn->update_cfg); | ||||||
|  | 		result_code=0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| //	conn->remote_cfg=params.cfg; | //	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. | 		 * Put further actions here, if needed. | ||||||
| 		 */ | 		 */ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (params.unrecognized) | 	if (params.unrecognized) | ||||||
| 		mlist_destroy(params.unrecognized); | 		mlist_destroy(params.unrecognized); | ||||||
| 	cw_cfg_destroy(params.cfg); | 	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)) { | 	if (cw_get_hdr_flag_f(packet)) { | ||||||
| 		/* fragmented, add the packet to fragman */ | 		/* fragmented, add the packet to fragman */ | ||||||
| 		uint8_t *f; | 		uint8_t *f,*fp; | ||||||
| 		int rc; | 		int rc; | ||||||
|  |  | ||||||
| 		f = fragman_add(conn->fragman, packet, offs, payloadlen); | 		fp = fragman_add(conn->fragman, packet, offs, payloadlen); | ||||||
| 		if (f == NULL) { | 		if (fp == NULL) { | ||||||
| 			errno = EAGAIN; | 			errno = EAGAIN; | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		f =fp+MAX_PKT_HDR_LEN; | ||||||
|  |  | ||||||
| 		cw_dbg_pkt(DBG_PKT_IN, conn, f + 4, *(uint32_t *) f, from); | 		cw_dbg_pkt(DBG_PKT_IN, conn, fp, *(uint32_t *) f+MAX_PKT_HDR_LEN, from); | ||||||
| /*//		cw_dbg_msg(DBG_MSG_IN, conn, f + 4, *(uint32_t *) f, from);*/ |  | ||||||
|  |  | ||||||
| /*		// XXX: Modify fragman to not throw away CAPWAP headers*/ |  | ||||||
|  |  | ||||||
| 		rc = conn->process_message(conn, f + 4, *(uint32_t *) f, from); | 		rc = conn->process_message(conn, f + 4, *(uint32_t *) f, from); | ||||||
|  |  | ||||||
| 		free(f); | 		free(fp); | ||||||
| 		return rc; | 		return rc; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -58,6 +58,8 @@ struct cw_action_in; | |||||||
| struct cw_Conn { | struct cw_Conn { | ||||||
| 	int sock; | 	int sock; | ||||||
| 	struct sockaddr_storage addr; | 	struct sockaddr_storage addr; | ||||||
|  | 	char remote_addr[64];	/* Contains a printfable string, of the connections | ||||||
|  | 				   peer address */ | ||||||
|  |  | ||||||
| 	struct connlist * connlist; | 	struct connlist * connlist; | ||||||
|  |  | ||||||
| @ -71,19 +73,19 @@ struct cw_Conn { | |||||||
| 	int recv_timeout; | 	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. | 				     which is using this conn object. | ||||||
| 				     Teh global_cfg has to be treated read-only. */ | 				     Teh global_cfg has to be treated read-only. */ | ||||||
|  |  | ||||||
| 	cw_Cfg_t * local_cfg;	/**< local_cfg contains overrides for global_cfg  | 	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  | 	cw_Cfg_t * remote_cfg;	/**< contains the configuration we now from the  | ||||||
| 				     device this conn object ist connected to. | 				     device this conn object ist connected to. | ||||||
| 				     Typically this is what we have got from discovery | 				     Typically this is what we have got from discovery | ||||||
| 				     response or join response in WTP mode.  | 				     response or join response in WTP mode.  | ||||||
| 				     And in AC mode this contains date receive from  | 				     And in AC mode this contains datia received by  | ||||||
| 				     configuration status request.  */ | 				     configuration status and join request.  */ | ||||||
|  |  | ||||||
| 	cw_Cfg_t * update_cfg; | 	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); | 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); | cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type); | ||||||
|  |  | ||||||
| int cw_decode_element(struct cw_ElemHandlerParams *params, int proto, | 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]; | 	char mkey[CW_CFG_MAX_KEY_LEN]; | ||||||
| 	const char *key; | 	const char *key; | ||||||
|  |  | ||||||
|  | //	cw_dbg(DBG_X,"HK: %s",handler->key,); | ||||||
|  |  | ||||||
| 	if (!type){ | 	if (!type){ | ||||||
| 		cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); | 		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{ | 	else{ | ||||||
| 		key = handler->key; | 		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); | 	type->read(params->cfg, key,elem_data,elem_len,handler->param); | ||||||
| 	return CAPWAP_RESULT_SUCCESS; | 	return CAPWAP_RESULT_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | int cw_out_generic0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params | ||||||
| 			, uint8_t * dst) | 			, uint8_t * dst,const char *key) | ||||||
| { | { | ||||||
|  |  | ||||||
| 	int start, len, l; | 	int start, len, l; | ||||||
| 	 | 	 | ||||||
| //	cw_dbg(DBG_X,"cw_out_generic (%s)%s",((struct cw_Type*)handler->type)->name,handler->key); | //	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_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); | ||||||
| //	cw_cfg_dump(params->cfg); | //	cw_cfg_dump(params->cfg); | ||||||
| //	cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!! ENDDUMP"); | //	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); | 	start = params->msgset->header_len(handler); | ||||||
| 	len = ((const cw_Type_t*)(handler->type))-> | 	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); | //	cw_dbg(DBG_X, "Type result is %d",len); | ||||||
|  |  | ||||||
| 	if (len == -1) { | 	if (len == -1) { | ||||||
| @ -62,7 +70,7 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams | |||||||
| 			cw_log(LOG_ERR, | 			cw_log(LOG_ERR, | ||||||
| 			       "Can't put mandatory element %s %d-(%s) into %s. No value for '%s' found.", | 			       "Can't put mandatory element %s %d-(%s) into %s. No value for '%s' found.", | ||||||
| 				vendor, handler->id, handler->name, params->msgdata->name | 				vendor, handler->id, handler->name, params->msgdata->name | ||||||
| 			       , handler->key | 			       , key | ||||||
| 			    ); | 			    ); | ||||||
| 		} | 		} | ||||||
| 		else{ | 		else{ | ||||||
| @ -79,6 +87,15 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams | |||||||
| 	l = params->msgset->write_header(handler,dst,len); | 	l = params->msgset->write_header(handler,dst,len); | ||||||
|  |  | ||||||
| 	return l; | 	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); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -118,6 +135,39 @@ int cw_out_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerP | |||||||
| 	int radios; | 	int radios; | ||||||
| 	len =0; | 	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); | 	radios = cw_cfg_get_byte_l(params->cfg_list,"capwap/wtp-descriptor/max-radios",0); | ||||||
| 	for(i=0;i<radios;i++){ | 	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; | 	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); | 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)) | #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_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 "dbg.h" | ||||||
| #include "cw.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 |  * @param conn Connection object | ||||||
|  * @retval 1 NAT detected |  * @retval 1 NAT detected | ||||||
|  * @retval 0 no NAT was detected |  * @retval 0 no NAT was detected | ||||||
| @ -15,7 +16,8 @@ int cw_detect_nat(struct cw_ElemHandlerParams *params) | |||||||
| 	const char  * remote_str; | 	const char  * remote_str; | ||||||
| 	char local_str[128]; | 	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){ | 	if (remote_str == NULL){ | ||||||
| 		cw_dbg(DBG_WARN,"Can't detect NAT. No local IP from peer received."); | 		cw_dbg(DBG_WARN,"Can't detect NAT. No local IP from peer received."); | ||||||
| 		return 0; | 		return 0; | ||||||
| @ -29,9 +31,12 @@ int cw_detect_nat(struct cw_ElemHandlerParams *params) | |||||||
| 	 | 	 | ||||||
| 	/* if connected and sent address is the same, there is  | 	/* if connected and sent address is the same, there is  | ||||||
| 	 * no NAT */ | 	 * 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; | 		return 0; | ||||||
|  | 	}		 | ||||||
| 	/* otherwise ther must be something between AC and WTP */ | 	/* otherwise ther must be something between AC and WTP */ | ||||||
|  | 	cw_dbg(DBG_INFO,"Connection from %s: NAT detected.",local_str); | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -3,105 +3,104 @@ | |||||||
| #include "conn.h" | #include "conn.h" | ||||||
| #include "cw.h" | #include "cw.h" | ||||||
|  |  | ||||||
| /** | #include "dot11.h" | ||||||
|  * @brief Format a packet header for debugging purposes |  | ||||||
|  * @param dst Destination buffer | int cw_format_dot11_fc_flags(char *dst, uint8_t *frame){ | ||||||
|  * @param incomming True if the packet is an incomming packet, otherweise 0 | 	char *s = dst; | ||||||
|  * @param packet packet data | 	uint8_t f = frame[0]; | ||||||
|  * @param len length of packet data | 	s+=sprintf(s,"ToDS:%d ", f&1 ? 1:0); | ||||||
|  * @param from Address from where the packet was received | 	s+=sprintf(s,"FromDS:%d ", f&2 ? 1:0); | ||||||
|  * @return Number of bytes written | 	s+=sprintf(s,"More Frgs:%d ", f&4 ? 1:0); | ||||||
|  */ | 	s+=sprintf(s,"Retry:%d ", f&8 ? 1:0); | ||||||
| int cw_format_pkt_hdr(char *dst, int incomming, uint8_t * packet, int len, | 	s+=sprintf(s,"PwrMgmt:%d ", f&16 ? 1:0); | ||||||
| 		      struct sockaddr *from) | 	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; | 	char *s; | ||||||
| 	int hlen, rid, wbid; | 	int type = dot11_get_type_and_subtype(packet); | ||||||
| 	int frag_id,frag_offs; |  | ||||||
|  |  | ||||||
| 	s = dst; | 	s=dst; | ||||||
|  |  | ||||||
| 	if (incomming){ | 	s+=sprintf(s,"IEEE 802.11 - %s",dot11_get_frame_name(packet)); | ||||||
| 		if (cw_get_hdr_flag_f(packet)) { | 	s+=sprintf(s," da:"); | ||||||
| 			s += sprintf(s, "Fragment from %s", | 	s+=format_mac(s,dot11_get_da(packet),6);	 | ||||||
| 				     sock_addr2str_p(from,sock_buf)); | 	s+=sprintf(s," sa:"); | ||||||
| 		} else { | 	s+=format_mac(s,dot11_get_sa(packet),6);	 | ||||||
| 			s += sprintf(s, "From %s", sock_addr2str_p(from,sock_buf)); | 	s+=sprintf(s," bssid:"); | ||||||
| 		} | 	s+=format_mac(s,dot11_get_bssid(packet),6); | ||||||
| 	} | 	s+=sprintf(s," seq: %d\n",dot11_get_seq(packet)); | ||||||
| 	else{ | 	s+=cw_format_dot11_fc_flags(s,packet); | ||||||
| 		if (cw_get_hdr_flag_f(packet)) { | 	s+=sprintf(s,"\nDuration: %d",dot11_get_duration(packet)); | ||||||
| 			s += sprintf(s, "Fragment to %s", sock_addr2str(from,sock_buf)); | // | ||||||
| 		} else { | /*	switch (type){ | ||||||
| 			s += sprintf(s, "To %s", sock_addr2str(from,sock_buf)); | 		case DOT11_ASSOC_REQ: | ||||||
| 		} | 			s+=sprintf(s,"\n   ssid: %.*s",dot11_assoc_req_get_ssid_len(packet), | ||||||
| 	} | 					dot11_assoc_req_get_ssid(packet) | ||||||
| 	s += sprintf(s, " l=%d: ", len); | 			); | ||||||
|  | 			break; | ||||||
| 			 | 			 | ||||||
| 	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; |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -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, | int cw_in_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, | ||||||
| 		uint8_t * elem_data, int elem_len) | 		uint8_t * elem_data, int elem_len) | ||||||
| { | { | ||||||
|  | 	stop(); | ||||||
|  |  | ||||||
|  | 	/* | ||||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | 	char key[CW_CFG_MAX_KEY_LEN]; | ||||||
| 	int idx; | 	int idx; | ||||||
|  |  | ||||||
|  |  | ||||||
| 	cw_dbg(DBG_X,"Fix cw_in_idx_generic_struct"); | 	cw_dbg(DBG_X,"Fix cw_in_idx_generic_struct"); | ||||||
| 	stop(); |  | ||||||
| 	 | 	 | ||||||
| 	if (!handler->type){ | 	if (!handler->type){ | ||||||
| 		cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name); | 		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); | 	sprintf(key, handler->key, idx); | ||||||
|  |  | ||||||
| 	cw_ktv_read_struct(params->cfg,handler->type,key,elem_data+1,elem_len-1); | 	cw_ktv_read_struct(params->cfg,handler->type,key,elem_data+1,elem_len-1); | ||||||
|  | */ | ||||||
| 	return CAPWAP_RESULT_SUCCESS; | 	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)); | 	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 |  * Get pointer to wireless specific data | ||||||
|  * @param th Pointer to packet |  * @param th Pointer to packet | ||||||
|  | |||||||
| @ -26,15 +26,16 @@ int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemH | |||||||
| 	 | 	 | ||||||
| 	e = ie->type; | 	e = ie->type; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	 | ||||||
| 	for(i=0; e[i].name!=NULL; i++) { | 	for(i=0; e[i].name!=NULL; i++) { | ||||||
| 		int b; | 		int b; | ||||||
| 		sprintf(key,"%s/%s",handler->key,e[i].name); | 		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){ | 		if (!b){ | ||||||
| 			stop(); | 			//stop(); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 		start = params->msgset->header_len(handler); | 		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(); | 	stop(); | ||||||
|  | /* | ||||||
| 	char key[CW_CFG_MAX_KEY_LEN]; | 	char key[CW_CFG_MAX_KEY_LEN]; | ||||||
| 	struct cw_Val * elem, search; | 	struct cw_Val * elem, search; | ||||||
| 	int i; | 	int i; | ||||||
| @ -26,7 +26,7 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan | |||||||
| 		 | 		 | ||||||
| 		sprintf(key,handler->key,i); | 		sprintf(key,handler->key,i); | ||||||
| 		search.key=key; | 		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); | 		elem = mavl_get_first(params->cfg,&search); | ||||||
| 		if(elem != NULL){ | 		if(elem != NULL){ | ||||||
| 			printf("Elem key: %s\n",elem->key); | 			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++){ | 	for(i=1;i<radios+1;i++){ | ||||||
| 		l = cw_write_radio_element(handler,params,i,dst+len); | 		l = cw_write_radio_element(handler,params,i,dst+len); | ||||||
| 		cw_dbg_elem(DBG_ELEM_OUT,params->conn,params->msgdata->type,handler,dst,l); | 		cw_dbg_elem(DBG_ELEM_OUT,params->conn,params->msgdata->type,handler,dst,l); | ||||||
| 		len+=l; | 		len+=l; | ||||||
| 	} | 	} | ||||||
| */ | * / | ||||||
|  |  | ||||||
| 	return mdst-dst; | 	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); | 		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"); | 	sprintf(key, "%s/%s", prefix, "ssl-cipher"); | ||||||
| 	conn->dtls_cipher = cw_cfg_get(cfg, key, default_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"); | 	sprintf(key, "%s/%s", prefix, "ssl-psk"); | ||||||
| 	conn->dtls_psk = (bstr16_t)cw_cfg_get(cfg, key, NULL); | 	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: | 			default: | ||||||
| 				l = stru[i].len; | 				l = stru[i].len; | ||||||
| 				if (pos+l > 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); | 		l=stru[i].type->read(cfg,key,data+pos,l,stru[i].valguard); | ||||||
|  |  | ||||||
| 		 |  | ||||||
| //		printf("READ STRUCT (%d): %s: %s\n",pos,key,dbstr); | //		printf("READ STRUCT (%d): %s: %s\n",pos,key,dbstr); | ||||||
| 		 | 		 | ||||||
| 		if (stru[i].len==-1){ | 		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; | 	int pos, i; | ||||||
| 	const char * result; | 	const char * result; | ||||||
| 	int wrlen; | 	int wrlen; | ||||||
|  | 	int rc; | ||||||
|  |  | ||||||
| 	cw_Val_t val; | 	cw_Val_t val; | ||||||
| 	memset(&val,0,sizeof(cw_Val_t)); | 	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	 | 		else	 | ||||||
| 			sprintf(key,"%s",pkey); | 			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) { | 		if(result) { | ||||||
| //			char s[2048]; | //			char s[2048]; | ||||||
| //			result->type->to_str(result,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){ | 		if (!rc){ | ||||||
| 			cw_log(LOG_ERR,"Can't put %s, no value found, filling wth zeros.",key); | 			int l; | ||||||
| 			memset(dst+pos,0,stru[i].len); | 			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{ | 		else{ | ||||||
| 			struct cw_Type * type; | 			struct cw_Type * type; | ||||||
|  | |||||||
| @ -8,55 +8,38 @@ | |||||||
| int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list, | int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list, | ||||||
|                                  int subelem_id, const char * parent_key ) |                                  int subelem_id, const char * parent_key ) | ||||||
| { | { | ||||||
| 	char key[256]; | 	char key[CW_CFG_MAX_KEY_LEN]; | ||||||
| 	uint32_t vendor; | 	uint32_t vendor; | ||||||
| 	//bstr16_t version; | 	bstr16_t version; | ||||||
| 	const char *vendor_s; | 	const char *vendor_s; | ||||||
|  |  | ||||||
| 	uint8_t *d; | 	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); | 	sprintf (key, "%s/%s", parent_key, CW_SKEY_VENDOR); | ||||||
| 	vendor_s = cw_cfg_get_l (cfg_list, key, NULL); | 	vendor_s = cw_cfg_get_l (cfg_list, key, NULL); | ||||||
| 	 |  | ||||||
| 	if (vendor_s == NULL) { | 	if (vendor_s == NULL) { | ||||||
| 		cw_log (LOG_ERR, "Can't put subelem %s, no value of type Dword found.", key); | 		cw_log (LOG_ERR, "Can't put subelem %s, no value found. Setting zero.", key); | ||||||
| 		return 0; | 		vendor_s = "0"; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	vendor = atoi(vendor_s);	 | 	vendor = atoi(vendor_s);	 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	sprintf (key, "%s/%s", parent_key, CW_SKEY_VERSION); | 	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_l(cfg_list,key,NULL); | ||||||
|  | 	if (version == NULL) { | ||||||
| 	//version = cw_cfg_get_bstr16 (cfg, key, 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"); | ||||||
|  |  | ||||||
| 	if (val == NULL) { |  | ||||||
| 		cw_log (LOG_ERR, "Can't put subelem %s, no value of type Bstr16 found.", key); |  | ||||||
| 		return 0; |  | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	d = dst; | 	d = dst; | ||||||
| 	 | 	 | ||||||
| 	/* put vendor */ | 	/* put vendor */ | ||||||
| 	d += cw_put_dword(d, vendor); //->type->put (vendor, d); | 	d += cw_put_dword(d, vendor);  | ||||||
| 	 | 	 | ||||||
| 	/* put version */ | 	/* put version */ | ||||||
|  | 	d += cw_put_dword (d, (subelem_id << 16) | bstr16_len(version)); | ||||||
|  | 	d += cw_put_bstr16(d, version); | ||||||
|  |  | ||||||
| 	d += cw_put_dword (d, (subelem_id << 16) | val->type->len(val)); | 	free(version); | ||||||
| //	d += cw_put_bstr16(d, version); |  | ||||||
| 	d += val->type->put(val,d); |  | ||||||
|  |  | ||||||
| 	cw_val_destroy(val); |  | ||||||
|  |  | ||||||
| //	free(version); |  | ||||||
| 	 | 	 | ||||||
| 	return d-dst; | 	return d-dst; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										322
									
								
								src/cw/dbg.c
									
									
									
									
									
								
							
							
						
						
									
										322
									
								
								src/cw/dbg.c
									
									
									
									
									
								
							| @ -31,6 +31,7 @@ | |||||||
| #include "format.h" | #include "format.h" | ||||||
| #include "ansi_colors.h" | #include "ansi_colors.h" | ||||||
|  |  | ||||||
|  | #include "dot11.h" | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *@addtogroup DBG |  *@addtogroup DBG | ||||||
| @ -47,7 +48,114 @@ uint32_t cw_dbg_opt_display = DBG_DISP_COLORS; | |||||||
| /** | /** | ||||||
|  * Current debug level |  * 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_RFC, ANSI_BRED}, | ||||||
| 	{DBG_X, "\x1b[31m"}, | 	{DBG_X, "\x1b[31m"}, | ||||||
| 	{DBG_WARN, ANSI_CYAN}, | 	{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_DMP, ANSI_BCYAN },  | ||||||
| 	{DBG_CFG_UPDATES,ANSI_GREEN},	 | 	{DBG_CFG_UPDATES,ANSI_GREEN},	 | ||||||
|  |  | ||||||
| @ -117,23 +226,24 @@ static struct cw_StrListElem color_off[] = { | |||||||
| */ | */ | ||||||
|  |  | ||||||
| static struct cw_StrListElem prefix[] = { | static struct cw_StrListElem prefix[] = { | ||||||
| 	{DBG_INFO, 		"Info -"}, | 	{DBG_INFO, 		"Info - "}, | ||||||
| 	{DBG_PKT_IN, 		"Pkt In  -"}, | 	{DBG_PKT_IN, 		"Pkt In  - "}, | ||||||
| 	{DBG_PKT_OUT, 		"Pkt Out -"}, | 	{DBG_PKT_OUT, 		"Pkt Out - "}, | ||||||
| 	{DBG_MSG_IN, 		"Msg In  - "}, | 	{DBG_MSG_IN, 		"Msg In  - "}, | ||||||
| 	{DBG_MSG_OUT,		"Msg Out - "}, | 	{DBG_MSG_OUT,		"Msg Out - "}, | ||||||
|  |  | ||||||
| 	{DBG_ELEM_IN, 		"  Msg Element -"}, | 	{DBG_ELEM_IN, 		"  Msg Element - "}, | ||||||
| 	{DBG_ELEM_OUT,		"  Msg Element -"}, | 	{DBG_ELEM_OUT,		"  Msg Element - "}, | ||||||
| 	 | 	 | ||||||
| 	{DBG_MSG_ERR, 		"  Msg Error -"}, | 	{DBG_MSG_ERR, 		"  Msg Error - "}, | ||||||
| 	{DBG_PKT_ERR, 		"  Pkt Error -"}, | 	{DBG_PKT_ERR, 		"  Pkt Error - "}, | ||||||
| 	{DBG_ELEM_ERR, 		"  Elem Error -"}, | 	{DBG_ELEM_ERR, 		"  Elem Error - "}, | ||||||
| 	{DBG_RFC, 		"  RFC -"}, | 	{DBG_RFC, 		"  RFC - "}, | ||||||
| 	{DBG_DTLS, 		"DTLS - "}, | 	{DBG_DTLS, 		"DTLS - "}, | ||||||
| 	{DBG_DTLS_DETAIL,	 "DTLS - "}, | 	{DBG_DTLS_DETAIL,	 "DTLS - "}, | ||||||
| 	{DBG_WARN,	 	"  Warning - "}, | 	{DBG_WARN,	 	"Warning - "}, | ||||||
| 	{DBG_MOD, 		"Mod - "}, | 	{DBG_MOD, 		"Mod - "}, | ||||||
|  | 	{DBG_MOD_DETAIL,	"Mod - "}, | ||||||
| 	{DBG_STATE, 		"STATEMACHINE - "}, | 	{DBG_STATE, 		"STATEMACHINE - "}, | ||||||
| 	{DBG_CFG_UPDATES,	"Cfg - "}, | 	{DBG_CFG_UPDATES,	"Cfg - "}, | ||||||
|  |  | ||||||
| @ -183,13 +293,19 @@ const char *get_dbg_color_ontext(int level) | |||||||
|  |  | ||||||
| int cw_dbg_is_level(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; | 		return 1; | ||||||
|  |  | ||||||
| /*	if (level >= DBG_ALL ){ | /*	if (level >= DBG_ALL ){ | ||||||
| 		return 1; | 		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) | 		struct sockaddr *from) | ||||||
| { | { | ||||||
|  |  | ||||||
| /*	int hlen;*/ |  | ||||||
| 	char buf[1024]; | 	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)) | 	if (!cw_dbg_is_level(level)) | ||||||
| 		return; | 		return; | ||||||
| 	 | 	 | ||||||
| 	if (level == DBG_PKT_IN) | 	if (level == DBG_PKT_IN) | ||||||
| 		cw_format_pkt_hdr(buf, 1,  packet, len, from); | 		fmt_pkt_hdr(buf, 1,  packet, len, from); | ||||||
| 	else | 	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);*/ | /*	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); | 	int i,all; | ||||||
| 	avliter_foreach(&it) { | 	all = strcmp(level,"all")==0 ? 1: 0; | ||||||
| 	 | 	 | ||||||
| 		mbag_item_t *i = avliter_get(&it); | 	for(i=0; cw_dbg_strings[i].str != NULL; i++){ | ||||||
|  | 		if (strcmp(cw_dbg_strings[i].str,level)==0 || all){ | ||||||
| 		char buffer[1000]; | 			if (cw_dbg_strings[i].str_list==NULL) | ||||||
|  | 				cw_dbg_set_level(cw_dbg_strings[i].level,on); | ||||||
| 		struct cw_str * strings = cw_item_strings; | 			else { | ||||||
| 		 | 				const char **l; | ||||||
| 		const char * in = cw_strlist_get_str(strings,i->id); | 				for (l=cw_dbg_strings[i].str_list; *l; l++){ | ||||||
| 		 | 					if (!cw_dbg_set_level_from_str0(*l,on)){ | ||||||
| 		cw_format_item(buffer,i); | 						stop(); | ||||||
| 		printf("Item ID %d-%s: %s\n",i->id,in,buffer); | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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{ | enum cw_dbg_levels{ | ||||||
| 	/** Show headers of incomming/outgoing CAPWAP packets */ | 	/** Show headers of incomming/outgoing CAPWAP packets */ | ||||||
| 	DBG_PKT_IN 	= (1<<0),  | 	DBG_PKT_IN 	= 1,  | ||||||
| 	DBG_PKT_OUT 	= (1<<1),	 | 	DBG_PKT_OUT,	 | ||||||
|  |  | ||||||
| 	/** Hex-dump incomming/outgoing CAPWAP packets */ | 	/** Hex-dump incomming/outgoing CAPWAP packets */ | ||||||
| 	DBG_PKT_DMP_IN	= (1<<3), | 	DBG_PKT_DMP_IN, | ||||||
| 	DBG_PKT_DMP_OUT = (1<<4), | 	DBG_PKT_DMP_OUT, | ||||||
|  |  | ||||||
| 	/** Incomming CAPWAP packets with errors, wich would | 	/** Incomming CAPWAP packets with errors, wich would | ||||||
| 	    usually silently discarded */  | 	    usually silently discarded */  | ||||||
| 	DBG_PKT_ERR	= (1<<5), | 	DBG_PKT_ERR, | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
| 	/** Display incomming/outgoing CAPWAP/LWAPP messages */ | 	/** Display incomming/outgoing CAPWAP/LWAPP messages */ | ||||||
| 	DBG_MSG_IN	= (1<<6), | 	DBG_MSG_IN, | ||||||
| 	DBG_MSG_OUT	= (1<<7), | 	DBG_MSG_OUT, | ||||||
|  |  | ||||||
| 	/** Show hex-dump of messages */ | 	/** Show hex-dump of messages */ | ||||||
| 	DBG_MSG_DMP_IN	= (1<<8), | 	DBG_MSG_DMP_IN, | ||||||
| 	DBG_MSG_DMP_OUT	= (1<<9), | 	DBG_MSG_DMP_OUT, | ||||||
|  |  | ||||||
| 	/** Message errors */ | 	/** Message errors */ | ||||||
| 	DBG_MSG_ERR	= (1<<10), | 	DBG_MSG_ERR, | ||||||
|  |  | ||||||
| 	/** Show message elements in incomming/outgoing messages */ | 	/** Show message elements in incomming/outgoing messages */ | ||||||
| 	DBG_ELEM_IN	= (1<<11), | 	DBG_ELEM_IN, | ||||||
| 	DBG_ELEM_OUT	= (1<<12), | 	DBG_ELEM_OUT, | ||||||
|  |  | ||||||
| 	/** Show message element details  */ | 	/** Show message element details  */ | ||||||
| 	DBG_ELEM_DETAIL_IN = (1<<13), | 	DBG_ELEM_DETAIL_IN, | ||||||
| 	DBG_ELEM_DETAIL_OUT = (1<<14), | 	DBG_ELEM_DETAIL_OUT, | ||||||
|  |  | ||||||
| 	/** Error in msg elements */ | 	/** Error in msg elements */ | ||||||
| 	DBG_ELEM_ERR	= (1<<15), | 	DBG_ELEM_ERR, | ||||||
|  |  | ||||||
| 	/** hex dump elements */	 | 	/** hex dump elements */	 | ||||||
| 	DBG_ELEM_DMP	= (1<<16), | 	DBG_ELEM_DMP, | ||||||
|  |  | ||||||
| 	/** General infos, like CAPWAP state */ | 	/** General infos, like CAPWAP state */ | ||||||
| 	DBG_INFO	= (1<<17),	 | 	DBG_INFO,	 | ||||||
|  |  | ||||||
| 	/** Misc. warnings */ | 	/** Misc. warnings */ | ||||||
| 	DBG_WARN	= (1<<18), | 	DBG_WARN, | ||||||
|  |  | ||||||
| 	/** RFC related */ | 	/** RFC related */ | ||||||
| 	DBG_RFC		= (1<<19), | 	DBG_RFC, | ||||||
|  |  | ||||||
| 	/** DTLS related messages */ | 	/** DTLS related messages */ | ||||||
| 	DBG_DTLS	= (1<<20), | 	DBG_DTLS, | ||||||
|  |  | ||||||
| 	/** DTLS BIOs in/out */ | 	/** DTLS BIOs in/out */ | ||||||
| 	DBG_DTLS_BIO	= (1<<21), | 	DBG_DTLS_BIO, | ||||||
|  |  | ||||||
| 	/** Dump DTLS BIO i/o */ | 	/** Dump DTLS BIO i/o */ | ||||||
| 	DBG_DTLS_BIO_DMP = (1<<22), | 	DBG_DTLS_BIO_DMP, | ||||||
|  |  | ||||||
| 	/** Show DTLS Details */ | 	/** 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 */ | 	/** Debug Mods */ | ||||||
| 	DBG_MOD		= (1<<24), | 	DBG_MOD, | ||||||
| 	 | 	 | ||||||
|        	/**Debug State machine */ |        	/**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_X, | ||||||
| 	DBG_ALL 	= (0x7fffffff), |  | ||||||
|  | 	DBG_MOD_DETAIL, | ||||||
|  |  | ||||||
|  | 	DBG_ALL, | ||||||
|  |  | ||||||
|  |  | ||||||
| 	DBG_ELEM_DMP_IN	= 7, | 	DBG_ELEM_DMP_IN, | ||||||
| 	DBG_ELEM_DMP_OUT = 9, | 	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_display; | ||||||
| extern uint32_t cw_dbg_opt_level; | //extern uint32_t cw_dbg_opt_level; | ||||||
| extern struct cw_StrListElem cw_dbg_strings[]; | //extern struct cw_StrListElem cw_dbg_strings[]; | ||||||
|  |  | ||||||
| /* | /* | ||||||
| #define cw_dbg cw_dbg_colored | #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); | 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) | #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_DTLS_DETAIL, 	"dtls_detail"}, | ||||||
|  |  | ||||||
| 	{ DBG_CFG_UPDATES, 	"cfg_updates" }, | 	{ DBG_CFG_UPDATES, 	"cfg_updates" }, | ||||||
|  | 	{ DBG_X,		"x" }, | ||||||
|  |  | ||||||
| 	 | 	 | ||||||
| //	{DBG_CFG_DMP, "cfg_dmp" }, | //	{DBG_CFG_DMP, "cfg_dmp" }, | ||||||
| @ -85,9 +86,7 @@ struct cw_StrListElem cw_dbg_strings[] = { | |||||||
| 		DBG_ELEM_IN | DBG_ELEM_OUT | | 		DBG_ELEM_IN | DBG_ELEM_OUT | | ||||||
| 		DBG_MSG_ERR | DBG_ELEM_ERR | | 		DBG_MSG_ERR | DBG_ELEM_ERR | | ||||||
| 		DBG_PKT_ERR | DBG_RFC | DBG_WARN | 		DBG_PKT_ERR | DBG_RFC | DBG_WARN | ||||||
|  | 		| DBG_STATE | DBG_INFO), 			"std" }, | ||||||
|  |  | ||||||
| 		| DBG_STATE), 			"std" }, |  | ||||||
|  |  | ||||||
| 	{ DBG_ALL, 		"all"}, | 	{ DBG_ALL, 		"all"}, | ||||||
|  |  | ||||||
| @ -121,7 +120,7 @@ struct cw_dbg_cfgstrs cw_dbg_cfgstrs[] = { | |||||||
| 	{"elem_err",DBG_ELEM_ERR}, | 	{"elem_err",DBG_ELEM_ERR}, | ||||||
|  |  | ||||||
| 	{"dtls",DBG_DTLS}, | 	{"dtls",DBG_DTLS}, | ||||||
| 	{"dtls_dietail",DBG_DTLS_DETAIL}, | 	{"dtls_detail",DBG_DTLS_DETAIL}, | ||||||
| 	{"dtls_bio",DBG_DTLS_BIO}, | 	{"dtls_bio",DBG_DTLS_BIO}, | ||||||
| 	{"dtls_bio_dmp",DBG_DTLS_BIO_DMP}, | 	{"dtls_bio_dmp",DBG_DTLS_BIO_DMP}, | ||||||
|  |  | ||||||
|  | |||||||
| @ -38,3 +38,28 @@ const char * dot11_type_strings[]= | |||||||
| 	"Probe Req", | 	"Probe Req", | ||||||
| 	"Probe Resp" | 	"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> | #include <endian.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #include "strlist.h" | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @defgroup DOT11_FRAME_TYPES Frame Types |  * @defgroup DOT11_FRAME_TYPES Frame Types | ||||||
| @ -47,17 +48,17 @@ | |||||||
|  * |  * | ||||||
|  * @{ |  * @{ | ||||||
|  */ |  */ | ||||||
| #define DOT11_FC_ASSOC_REQ	dot11_fc_mgm(0b0000) | #define DOT11_ASSOC_REQ		dot11_fc_mgm(0b0000) | ||||||
| #define DOT11_FC_ASSOC_RESP	dot11_fc_mgm(0b0001) | #define DOT11_ASSOC_RESP	dot11_fc_mgm(0b0001) | ||||||
| #define DOT11_FC_REASSOC_REQ	dot11_fc_mgm(0b0010) | #define DOT11_REASSOC_REQ	dot11_fc_mgm(0b0010) | ||||||
| #define DOT11_FC_REASSOC_RESP	dot11_fc_mgm(0b0011) | #define DOT11_REASSOC_RESP	dot11_fc_mgm(0b0011) | ||||||
| #define DOT11_FC_PROBE_REQ	dot11_fc_mgm(0b0100) | #define DOT11_PROBE_REQ		dot11_fc_mgm(0b0100) | ||||||
| #define DOT11_FC_PROBE_RESP	dot11_fc_mgm(0b0101) | #define DOT11_PROBE_RESP	dot11_fc_mgm(0b0101) | ||||||
| #define DOT11_FC_TIMING_ADV	dot11_fc_mgm(0b0110) | #define DOT11_TIMING_ADV	dot11_fc_mgm(0b0110) | ||||||
| #define DOT11_FC_MGM_RES111	dot11_fc_mgm(0b0111) | #define DOT11_MGM_RES111	dot11_fc_mgm(0b0111) | ||||||
| #define DOT11_FC_BEACON		dot11_fc_mgm(0b1000) | #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  |  * @defgroup DOT11_ELEMS  | ||||||
|  * @{ |  * @{ | ||||||
|  */ |  */ | ||||||
| #define DOT11_ELEM_SSID			0 | #define DOT11_ELEM_SSID				0 | ||||||
| #define DOT11_ELEM_SUPPORTED_RATES	1 | #define DOT11_ELEM_SUPPORTED_RATES		1 | ||||||
| #define DOT11_ELEM_FH_PARAM_SET		2 | #define DOT11_ELEM_FH_PARAM_SET			2 | ||||||
| #define DOT11_ELEM_DSSS_PARAM_SET	3 | #define DOT11_ELEM_DSSS_PARAM_SET		3 | ||||||
| #define DOT11_ELEM_CF_PARAM_SET		4 | #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_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_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_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); | uint16_t dot11_get_word(uint8_t * ptr); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define dot11_get_version(frame) ((frame[1])&0x03) | #define dot11_get_version(frame) ( (frame)[1] & 0x03) | ||||||
| #define dot11_get_type(frame) (((frame[1])&0x0c) >> 2) | #define dot11_get_type(frame)    ( ((frame)[1] & 0x0c) >> 2) | ||||||
| #define dot11_get_subtype(frame) (((frame[1])&0xf0) >> 4) | #define dot11_get_subtype(frame) ( (frame)[1] >> 4 ) | ||||||
| /**  |  | ||||||
|  * Get Frame Control field  | #define dot11_get_type_and_subtype(frame) ((frame)[1]) | ||||||
|  * @param frame | #define dot11_set_type_and_subtype(frame,val) ((frame)[1]=val) | ||||||
|  * @return Frame Control field |  | ||||||
|  */ |  | ||||||
| #define dot11_get_fc(frame) dot11_get_word(frame) |  | ||||||
|  |  | ||||||
| #define dot11_get_duration(frame) dot11_get_word(frame+2) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void dot11_get_address(uint8_t * dst, uint8_t * frame); | 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_address(dst,addr) (memcpy(dst,addr,6),6) | ||||||
| #define dot11_put_sequence_control(dst,v) (dot11_put_word(dst,v)) | #define dot11_put_sequence_control(dst,v) (dot11_put_word(dst,v)) | ||||||
| #define dot11_put_capability(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); | 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; | 	return 1000000 * tv.tv_sec + tv.tv_usec - dot11_timer_offset; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void dot11_timer_set(uint64_t val) | void dot11_timer_set(uint64_t val) | ||||||
| { | { | ||||||
| 	struct timeval tv; | 	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){ | int  dot11_put_ssid(uint8_t *dst,uint8_t * ssid,int len){ | ||||||
| 	dot11_put_byte(dst,DOT11_ELEM_SSID); | 	dot11_set_byte(dst,DOT11_ELEM_SSID); | ||||||
| 	dot11_put_byte(dst+1,len); | 	dot11_set_byte(dst+1,len); | ||||||
| 	memcpy(dst+2,ssid,len); | 	memcpy(dst+2,ssid,len); | ||||||
| 	return len; | 	return len; | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int dot11_put_supported_rates(uint8_t *dst, float *basic, float *rates){ | 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) { | int dot11_put_dsss_param_set(uint8_t *dst,int ch) { | ||||||
|  |  | ||||||
| 	dot11_put_byte(dst,DOT11_ELEM_DSSS_PARAM_SET); | 	dot11_set_byte(dst,DOT11_ELEM_DSSS_PARAM_SET); | ||||||
| 	dot11_put_byte(dst+1,1); | 	dot11_set_byte(dst+1,1); | ||||||
| 	dot11_put_byte(dst+2,ch); | 	dot11_set_byte(dst+2,ch); | ||||||
| 	return 3; | 	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) | 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; | 		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); | 	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; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	/* set dtls psk if exists */ | 	/* set dtls psk if exists */ | ||||||
| /*	if (conn->dtls_psk) | /*	if (conn->dtls_psk) | ||||||
| 		SSL_CTX_set_psk_server_callback( d->ctx, psk_server_cb); | 		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; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	DTLS_set_timer_cb(d->ssl,timer_cb); | ||||||
| 	 | 	 | ||||||
| 	d->bio = BIO_new(bio); | 	d->bio = BIO_new(bio); | ||||||
| /*	d->bio->ptr = conn;*/ | /*	d->bio->ptr = conn;*/ | ||||||
|  | |||||||
							
								
								
									
										145
									
								
								src/cw/format.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								src/cw/format.c
									
									
									
									
									
								
							| @ -27,6 +27,10 @@ | |||||||
|  |  | ||||||
| #include "cw.h" | #include "cw.h" | ||||||
|  |  | ||||||
|  | #include "format.h" | ||||||
|  |  | ||||||
|  | #include "capwap80211.h" | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Format bytes as hex string. |  * Format bytes as hex string. | ||||||
|  * @param dst Destination buffer |  * @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); | 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. |  * 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); | void cw_format_get_dump_defaults(struct cw_FormatDumpSettings * settings); | ||||||
| int cw_format_pkt_hdr(char *dst, int incomming, uint8_t * packet, int len, | int cw_format_pkt_hdr(char *dst, int incomming, uint8_t * packet, int len, | ||||||
| 		      struct sockaddr *from); | 		      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); | 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 | #endif | ||||||
|  | |||||||
| @ -54,6 +54,7 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| #include "capwap.h" | #include "capwap.h" | ||||||
|  | #include "cw.h" | ||||||
| #include "fragman.h" | #include "fragman.h" | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -101,20 +102,6 @@ static struct frag * frag_new(struct frag * frags, int fragid) | |||||||
| 	return NULL; | 	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 |  * Add a fragment | ||||||
|  * @pram frags Fragman object |  * @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; | 	uint32_t val0,val1; | ||||||
| 	int fragid,fragoffset; | 	int fragid,fragoffset; | ||||||
| 	int dst; | 	int dst; | ||||||
| 	int ti; |  | ||||||
| 	 | 	 | ||||||
| 	/* read the transport header dword 0, | 	/* read the transport header dword 0, | ||||||
| 	 * contains hlen*/	 | 	 * contains hlen*/	 | ||||||
| 	val0 = ntohl(*((uint32_t*)packet)); | 	val0 = ntohl(*((uint32_t*)packet)); | ||||||
| /*	int hlen = (val0 >> 19) & 0x1f;*/ |  | ||||||
|  |  | ||||||
| 	/* read the transport header dword 1, | 	/* read the transport header dword 1, | ||||||
| 	 * contains fragid and fragoffset */	 | 	 * 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; | 	fragid = val1>>16; | ||||||
| 	fragoffset=(val1 >>3) & 0x1fff; | 	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 */ | 	/* find / create cfragment */ | ||||||
| 	f = frag_get(frags,fragid); | 	f = frag_get(frags,fragid); | ||||||
| 	if (!f){ | 	if (!f){ | ||||||
| 		f = frag_new(frags,fragid); | 		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; | 	errno = 0; | ||||||
|  |  | ||||||
| 	dst = fragoffset*8; | 	dst = fragoffset*8; | ||||||
|  |  | ||||||
| 	/* copy fragment*/ | 	/* copy fragment*/ | ||||||
| 	if (dst + payloadlen < FRAG_MAXSIZE) { | 	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; | 		f->bytesreceived+=payloadlen; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -177,21 +159,13 @@ uint8_t * fragman_add(frag_t * frags, uint8_t *packet, int hlen, int payloadlen) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	for (ti=0; ti<16; ti++){ |  | ||||||
| /*//		printf("%02X ",(f->buffer+4)[ti]);*/ |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (f->bytesneeded>0 && f->bytesneeded<=f->bytesreceived){ | 	if (f->bytesneeded>0 && f->bytesneeded<=f->bytesreceived){ | ||||||
| 		uint8_t * r=f->buffer; | 		uint8_t * r=f->buffer; | ||||||
| 		f->buffer=0; | 		f->buffer=0; | ||||||
| /*//		printf("last bytes need %i\n",f->bytesneeded);*/ | 		*((uint32_t*)(r+MAX_PKT_HDR_LEN))=f->bytesneeded; | ||||||
| 		*((uint32_t*)(r))=f->bytesneeded; |  | ||||||
| 		return r;  | 		return r;  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| /*//	printf("Fragman bytes needed: %i, received  %i\n",f->bytesneeded,f->bytesreceived);*/ |  | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -19,9 +19,9 @@ | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  *@defgroup Fragman FRAGMAN |  *@defgroup Fragman FRAGMAN | ||||||
|  *@breif Frgaman functions |  *@brief Frgaman functions | ||||||
|  * |  * | ||||||
|  * Detailed esription |  * Detailed desription | ||||||
|  *@{ |  *@{ | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| @ -33,18 +33,18 @@ | |||||||
| #include <time.h> | #include <time.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  |  | ||||||
| #ifndef FRAG_MAXSIZE |  | ||||||
| 	/** maximaum size of a fragment */ |  | ||||||
| 	#define FRAG_MAXSIZE 65536+4 |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #ifndef FRAG_MAXIDS | #define MAX_PKT_HDR_LEN 64 | ||||||
| 	#define FRAG_MAXIDS 10 |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #ifndef FRAG_TTL | /** maximaum size of a fragment */ | ||||||
| 	#define FRAG_TTL 5 | #define FRAG_MAXSIZE (65536+MAX_PKT_HDR_LEN) | ||||||
| #endif |  | ||||||
|  | #define FRAG_MAXIDS 10 | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * TTL of received fragment in seconds | ||||||
|  |  */ | ||||||
|  | #define FRAG_TTL 5  | ||||||
|  |  | ||||||
|  |  | ||||||
| struct frag { | struct frag { | ||||||
| @ -57,7 +57,7 @@ struct frag { | |||||||
| 	int bytesreceived; | 	int bytesreceived; | ||||||
| 	int bytesneeded; | 	int bytesneeded; | ||||||
| 	struct timespec t; | 	struct timespec t; | ||||||
| 	uint8_t * header; | //	uint8_t * header; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef struct frag frag_t; /*FRAGMAN;*/ | typedef struct frag frag_t; /*FRAGMAN;*/ | ||||||
|  | |||||||
| @ -137,7 +137,7 @@ | |||||||
| #define LW_ELEM_DIRECT_SEQUENCE_CONTROL			14 | #define LW_ELEM_DIRECT_SEQUENCE_CONTROL			14 | ||||||
|  |  | ||||||
| #define LW_ELEM_CHANGE_STATE_EVENT			26 | #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_AC_NAME					31 | ||||||
| #define LW_ELEM_LOCATION_DATA				35 | #define LW_ELEM_LOCATION_DATA				35 | ||||||
| @ -151,7 +151,7 @@ | |||||||
|  |  | ||||||
| #define LW_ELEM_CERTIFICATE				44 | #define LW_ELEM_CERTIFICATE				44 | ||||||
| #define LW_ELEM_WTP_BOARD_DATA				50 | #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_WTP_MODE_AND_TYPE			54 | ||||||
| #define LW_ELEM_QOS					57 | #define LW_ELEM_QOS					57 | ||||||
|  |  | ||||||
|  | |||||||
| @ -38,16 +38,16 @@ int cw_encode_elements(struct cw_ElemHandlerParams *params, mlist_t elements_lis | |||||||
| 			} | 			} | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  | /* | ||||||
| 		if (!data->mand){ | 		if (!data->mand){ | ||||||
| 			if (!cw_cfg_base_exists(params->cfg_list[0],handler->key)){ | 			if (!cw_cfg_base_exists(params->cfg_list[0],handler->key)){ | ||||||
| 				cw_dbg(DBG_MSG_COMPOSE,"    Add Elem: %d %d %d %s - (skip)",  | 				cw_dbg(DBG_MSG_COMPOSE,"    Add Elem: %d %d %d %s %s - (skip)",  | ||||||
| 						data->proto, data->vendor, data->id, handler->name); | 						data->proto, data->vendor, data->id, handler->name, handler->key); | ||||||
|  |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | */ | ||||||
|  |  | ||||||
| 		l = handler->put(handler,params,dst+len); | 		l = handler->put(handler,params,dst+len); | ||||||
| 		cw_dbg(DBG_MSG_COMPOSE,"    Add Elem: %d %d %d %s - (%d bytes)",  | 		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 */ | 	/* check the length of the message */ | ||||||
| 	if (len < handler->min_len) { | 	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, | 		cw_dbg(DBG_ELEM_ERR, | ||||||
| 		       "%d (%s) message element too short, len=%d, min len=%d", | 		       "%d (%s) message element too short, len=%d, min len=%d", | ||||||
| 		       handler->id, handler->name, len, handler->min_len); | 		       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 (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, | 		cw_dbg(DBG_ELEM_ERR, | ||||||
| 		       "%d (%s) message element too big, len=%d, max len=%d", | 		       "%d (%s) message element too big, len=%d, max len=%d", | ||||||
| 		       handler->id, handler->name, len, handler->max_len); | 		       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 | 	/* Search for the module in mods_loaded, to see if it is | ||||||
| 	 * already loaded or was statically linked */ | 	 * 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)); | 	memset(&search, 0, sizeof(search)); | ||||||
| 	search.name = mod_name; | 	search.name = mod_name; | ||||||
|  |  | ||||||
| 	mod = mavl_get_ptr(mods_loaded, &search); | 	mod = mavl_get_ptr(mods_loaded, &search); | ||||||
| 	if (mod) { | 	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; | 		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) | 	if (filename == NULL) | ||||||
| 		return 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 */ | 	/* Open the DLL */ | ||||||
| 	handle = dlopen(filename, RTLD_NOW); | 	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; | 		goto errX; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cw_dbg(DBG_MOD, "MOD: %s sucessfull loaded, calling init now.", filename); | 	cw_dbg(DBG_MOD, "Module %s sucessfull loaded, calling init now.", filename); | ||||||
| 	mod->init(mod, global_cfg, role); | 	if (!mod->init(mod, global_cfg, role)){ | ||||||
|  | 		dlclose(handle); | ||||||
|  | 		mod=NULL; | ||||||
|  | 	}		 | ||||||
| 	 | 	 | ||||||
|       errX: |       errX: | ||||||
| 	free(filename); | 	free(filename); | ||||||
|  | |||||||
| @ -56,7 +56,7 @@ struct cw_Mod { | |||||||
| 		int elems_len, struct sockaddr * from, int mode); | 		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  | 	 * 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; | 				break; | ||||||
| 				continue; | 				continue; | ||||||
| 			case CW_DELETE: | 			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->proto, | ||||||
| 				       elemdef->vendor, elemdef->id, handler->name); | 				       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); | 		result = mavl_replace(msgdata->elements_tree, &ed, &replaced); | ||||||
|  |  | ||||||
| 		if (!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->proto, | ||||||
| 			       elemdef->vendor, elemdef->id, handler->name); | 			       elemdef->vendor, elemdef->id, handler->name); | ||||||
| 		} else { | 		} 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->proto, | ||||||
| 			       elemdef->vendor, elemdef->id, handler->name); | 			       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); | 						    result->vendor, result->id); | ||||||
| 		if (result->mand){ | 		if (result->mand){ | ||||||
| 			mlist_append_ptr(msgdata->mand_keys,(void*)handler->key); | 			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);*/ | 		/*//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; | 	struct cw_MsgDef *msgdef; | ||||||
| 	/* Create mavl for all handlers */ | 	/* Create mavl for all handlers */ | ||||||
| 	for (handler = handlers; handler->id; handler++) { | 	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); | 		       handler->id, handler->name, handler->key); | ||||||
| 		mavl_replace(set->handlers_by_id, handler, NULL); | 		mavl_replace(set->handlers_by_id, handler, NULL); | ||||||
| 		mavl_replace(set->handlers_by_key, 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; | 		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); | 		update_msgdata(set, msg, msgdef); | ||||||
| @ -376,7 +376,7 @@ int cw_msgset_add_states(struct cw_MsgSet * set, cw_StateMachineState_t * states | |||||||
| 		else{ | 		else{ | ||||||
| 			repstr = "Adding"; | 			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->prevstate), | ||||||
| 			cw_strstate(s->state)); | 			cw_strstate(s->state)); | ||||||
| 		s++; | 		s++; | ||||||
| @ -405,7 +405,9 @@ struct cw_MsgData *cw_msgset_get_msgdata(struct cw_MsgSet *set, int type) | |||||||
| 	return NULL; | 	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 cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id, | ||||||
| 	cw_MsgCallbackFun fun) | 	cw_MsgCallbackFun fun) | ||||||
|  |  | ||||||
| @ -420,5 +422,5 @@ cw_MsgCallbackFun cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id, | |||||||
| 	return old_callback; | 	return old_callback; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | |||||||
| @ -72,6 +72,9 @@ struct cw_MsgSet { | |||||||
| 	mavl_t statemachine_states; | 	mavl_t statemachine_states; | ||||||
| 	int (*write_header)(struct cw_ElemHandler * handler, uint8_t * dst, int len); | 	int (*write_header)(struct cw_ElemHandler * handler, uint8_t * dst, int len); | ||||||
| 	int (*header_len)(struct cw_ElemHandler *handler); | 	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_POSTPROCESS	1 | ||||||
| #define CW_MSGSET_PREPROCESS	2 | #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 cw_msgset_set_postprocess(struct cw_MsgSet * set,int msg_id, | //	cw_MsgCallbackFun fun); | ||||||
| 	cw_MsgCallbackFun fun); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif | #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