mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-30 18:07:52 +00:00 
			
		
		
		
	opensync: Added support for local dhcp fingerprint decoding
- Support to decode dhcp fingerprint using a locally stored fingerbank database Fixes: WIFI-433 Signed-off-by: Yashvardhan <yashvardhan@netexperience.com>
This commit is contained in:
		 Yashvardhan
					Yashvardhan
				
			
				
					committed by
					
						 John Crispin
						John Crispin
					
				
			
			
				
	
			
			
			 John Crispin
						John Crispin
					
				
			
						parent
						
							9934f93701
						
					
				
				
					commit
					61ad8756b3
				
			
							
								
								
									
										4768
									
								
								feeds/wlan-ap/opensync/files/etc/dhcp_fingerprints.db
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4768
									
								
								feeds/wlan-ap/opensync/files/etc/dhcp_fingerprints.db
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,6 +1,6 @@ | ||||
| --- a/interfaces/opensync.ovsschema | ||||
| +++ b/interfaces/opensync.ovsschema | ||||
| @@ -2657,6 +2657,41 @@ | ||||
| @@ -2657,6 +2657,69 @@ | ||||
|                "type": "integer" | ||||
|              } | ||||
|            } | ||||
| @@ -38,6 +38,34 @@ | ||||
| +            "key": { | ||||
| +              "type": "string" | ||||
| +            } | ||||
| +          } | ||||
| +        }, | ||||
| +        "db_status": { | ||||
| +          "type": { | ||||
| +            "key": { | ||||
| +              "type": "integer" | ||||
| +            } | ||||
| +          } | ||||
| +        }, | ||||
| +        "device_name": { | ||||
| +          "type": { | ||||
| +            "key": { | ||||
| +              "type": "string" | ||||
| +            } | ||||
| +          } | ||||
| +        }, | ||||
| +        "device_type": { | ||||
| +          "type": { | ||||
| +            "key": { | ||||
| +              "type": "integer" | ||||
| +            } | ||||
| +          } | ||||
| +        }, | ||||
| +        "manuf_id": { | ||||
| +          "type": { | ||||
| +            "key": { | ||||
| +              "type": "integer" | ||||
| +            } | ||||
| +          } | ||||
|          } | ||||
|        }, | ||||
|   | ||||
| @@ -0,0 +1,67 @@ | ||||
| /* SPDX-License-Identifier: BSD-3-Clause */ | ||||
|  | ||||
| #ifndef _DHCP_FINGERPRINT_H_ | ||||
| #define _DHCP_FINGERPRINT_H_ | ||||
|  | ||||
| #include "netifd.h" | ||||
|  | ||||
| #define MAX_DHCP_FINGERPRINT_OPTION_SEQ		256 | ||||
| #define MAX_FINGERPRINT_DEVICE_DESCRIPTION	256 | ||||
| #define MAX_DHCP_FINGERPRINT_LOCAL_DB	64 | ||||
| #define DHCP_FINGERPRINT_DB_FILE 	"/etc/dhcp_fingerprints.db" | ||||
|  | ||||
| typedef enum { | ||||
| 	DHCP_FP_DB_SUCCESS = 0, | ||||
| 	DHCP_FP_DB_FAILURE | ||||
| } dhcp_fp_dbstatus_t; | ||||
|  | ||||
| typedef enum { | ||||
| 	DHCP_FP_DEV_TYPE_MISC = 0, | ||||
| 	DHCP_FP_DEV_TYPE_MOBILE = 1, | ||||
| 	DHCP_FP_DEV_TYPE_PC = 2, | ||||
| 	DHCP_FP_DEV_TYPE_PRINTER = 3, | ||||
| 	DHCP_FP_DEV_TYPE_VIDEO = 4, | ||||
| 	DHCP_FP_DEV_TYPE_GAME = 5, | ||||
| 	DHCP_FP_DEV_TYPE_VOIP = 6, | ||||
| 	DHCP_FP_DEV_TYPE_MONITORING = 7, | ||||
| 	DHCP_FP_DEV_TYPE_MAX	= 8 | ||||
| } dhcp_fp_devicetype_t; | ||||
|  | ||||
| typedef enum { | ||||
| 	DHCP_FP_DEV_MANUF_MISC = 0, | ||||
| 	DHCP_FP_DEV_MANUF_SAMSUNG = 1, | ||||
| 	DHCP_FP_DEV_MANUF_APPLE = 2, | ||||
| 	DHCP_FP_DEV_MANUF_GOOGLE = 3, | ||||
| 	DHCP_FP_DEV_MANUF_HP = 4, | ||||
| 	DHCP_FP_DEV_MANUF_INTEL = 5, | ||||
| 	DHCP_FP_DEV_MANUF_MICROSOFT = 6, | ||||
| 	DHCP_FP_DEV_MANUF_LG = 7, | ||||
| 	DHCP_FP_DEV_MANUF_CANON = 8, | ||||
| 	DHCP_FP_DEV_MANUF_BROTHER = 9, | ||||
| 	DHCP_FP_DEV_MANUF_DELL = 10, | ||||
| 	DHCP_FP_DEV_MANUF_LENOVO = 11, | ||||
| 	DHCP_FP_DEV_MANUF_VIVO = 12, | ||||
| 	DHCP_FP_DEV_MANUF_ALCATEL = 13, | ||||
| 	DHCP_FP_DEV_MANUF_ZTE = 14, | ||||
| 	DHCP_FP_DEV_MANUF_SONY = 15, | ||||
| 	DHCP_FP_DEV_MANU_MAX = 16 | ||||
| } dhcp_fp_manufid_t; | ||||
|  | ||||
|  | ||||
| typedef struct { | ||||
| 	dhcp_fp_dbstatus_t db_status; | ||||
| 	char option_seq[MAX_DHCP_FINGERPRINT_OPTION_SEQ]; | ||||
| 	char device_name[MAX_FINGERPRINT_DEVICE_DESCRIPTION]; | ||||
| 	dhcp_fp_devicetype_t device_type; | ||||
| 	dhcp_fp_manufid_t manuf_id; | ||||
| } dhcp_fp_data_t; | ||||
|  | ||||
| typedef struct { | ||||
| 	int db_num; | ||||
| 	dhcp_fp_data_t devices[MAX_DHCP_FINGERPRINT_LOCAL_DB]; | ||||
| 	int index; | ||||
| }dhcp_fp_localdb_t; | ||||
|  | ||||
| bool dhcp_fp_db_lookup (dhcp_fp_data_t *fp_data, char *option_seq); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										129
									
								
								feeds/wlan-ap/opensync/src/platform/openwrt/src/netifd/src/dhcp_fingerprint.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										129
									
								
								feeds/wlan-ap/opensync/src/platform/openwrt/src/netifd/src/dhcp_fingerprint.c
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| /* SPDX-License-Identifier: BSD-3-Clause */ | ||||
|  | ||||
| #include "netifd.h" | ||||
| #include "dhcp_fingerprint.h" | ||||
|  | ||||
| dhcp_fp_localdb_t local_db; | ||||
|  | ||||
| bool dhcp_fp_db_lookup (dhcp_fp_data_t *fp_data, char *option_seq) | ||||
| { | ||||
| 	FILE *fp = NULL; | ||||
| 	char *line = NULL; | ||||
| 	int i, rd, rt, found = 0; | ||||
| 	size_t len; | ||||
| 	int dev_type, dev_manufid = 0; | ||||
|  | ||||
| 	memset(fp_data, 0, sizeof(dhcp_fp_data_t)); | ||||
|  | ||||
| 	/* first, try to find it from local db */ | ||||
| 	for (i=0; i < local_db.db_num; i++) { | ||||
| 		if (!strncmp(local_db.devices[i].option_seq, option_seq, MAX_DHCP_FINGERPRINT_OPTION_SEQ)) { | ||||
| 			LOG(INFO, "found a match from db cache"); | ||||
|  | ||||
| 			strcpy(fp_data->device_name, local_db.devices[i].device_name); | ||||
| 			fp_data->device_type = local_db.devices[i].device_type; | ||||
| 			fp_data->manuf_id = local_db.devices[i].manuf_id; | ||||
| 			fp_data->db_status = local_db.devices[i].db_status;; | ||||
|  | ||||
| 			return true; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	fp = fopen(DHCP_FINGERPRINT_DB_FILE, "r"); | ||||
| 	if (fp == NULL){ | ||||
| 		LOG(ERR, "fingerprints.conf file does not exist"); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	while ((rd = getline(&line, &len, fp)) != -1) { | ||||
| 		if (rd < 0) | ||||
| 			continue; | ||||
|  | ||||
| 		if (line[0] == '#') | ||||
| 			continue; | ||||
|  | ||||
| 		if (rd -1 >= 0) | ||||
| 			line[rd - 1] = '\0'; | ||||
| 		else continue; | ||||
|  | ||||
| 		if ((rt =strncmp(option_seq, &(line[0]), strlen(option_seq))) == 0) { | ||||
| 			if ((rd = getline(&line, &len, fp)) < 0) { | ||||
| 				LOG(ERR, "db file is in wrong format, device name"); | ||||
| 				goto db_lookup_exit; | ||||
| 			} | ||||
|  | ||||
| 			if ((rd >= MAX_FINGERPRINT_DEVICE_DESCRIPTION) || (rd - 1 < 0)) { | ||||
| 				LOG(ERR, "device name length from db:%d", rd); | ||||
| 				goto db_lookup_exit; | ||||
| 			} | ||||
| 			line[rd - 1] = '\0'; | ||||
| 			strncpy(fp_data->device_name, &(line[0]), MAX_FINGERPRINT_DEVICE_DESCRIPTION); | ||||
| 			fp_data->db_status = DHCP_FP_DB_SUCCESS; | ||||
|  | ||||
|  | ||||
| 			if ((rd = getline(&line, &len, fp)) < 0) { | ||||
| 				LOG(ERR, "db file is in wrong format, device type"); | ||||
| 				goto db_lookup_exit; | ||||
| 			} | ||||
| 			line[rd - 1] = '\0'; | ||||
| 			dev_type = atoi(&(line[0])); | ||||
| 			if (dev_type >= DHCP_FP_DEV_TYPE_MAX) { | ||||
| 				LOG(ERR, "db file is in wrong format, device type:%d", dev_type); | ||||
| 				goto db_lookup_exit; | ||||
| 			} | ||||
|  | ||||
|  | ||||
| 			if ((rd = getline(&line, &len, fp)) < 0) { | ||||
| 				LOG(ERR, "db file is in wrong format, manufacturer id"); | ||||
| 				goto db_lookup_exit; | ||||
| 			} | ||||
|  | ||||
| 			line[rd - 1] = '\0'; | ||||
| 			dev_manufid = atoi(&(line[0])); | ||||
| 			if (dev_manufid >= DHCP_FP_DEV_MANU_MAX) { | ||||
| 				LOG(ERR, "db file is in wrong format, manufacturer id:%d", dev_manufid); | ||||
| 				goto db_lookup_exit; | ||||
| 			} | ||||
|  | ||||
| 			fp_data->device_type = dev_type; | ||||
| 			fp_data->manuf_id = dev_manufid; | ||||
| 			fp_data->db_status = DHCP_FP_DB_SUCCESS; | ||||
| 			found = 1; | ||||
|  | ||||
| 			LOG(DEBUG, "match found, localDbEntries:%d, device_name:%s added to index:%d", local_db.db_num, fp_data->device_name, local_db.index-1); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!found) { | ||||
| 		LOGN("dhcp option seq not found in the db, seq=%s", option_seq); | ||||
| 		fp_data->db_status = DHCP_FP_DB_FAILURE; | ||||
| 		fp_data->manuf_id = DHCP_FP_DEV_MANUF_MISC; | ||||
| 		fp_data->device_type = DHCP_FP_DEV_TYPE_MISC; | ||||
| 		fp_data->device_name[0] = '\0'; | ||||
| 	} | ||||
|  | ||||
| 	/* store in the local database */ | ||||
| 	memcpy(local_db.devices[local_db.index].option_seq, option_seq, MAX_DHCP_FINGERPRINT_OPTION_SEQ); | ||||
| 	strcpy(local_db.devices[local_db.index].device_name, fp_data->device_name); | ||||
| 	local_db.devices[local_db.index].device_type = fp_data->device_type; | ||||
| 	local_db.devices[local_db.index].manuf_id = fp_data->manuf_id; | ||||
| 	local_db.devices[local_db.index].db_status = fp_data->db_status; | ||||
|  | ||||
| 	LOG(DEBUG, "db added, option_seq:%s, name:%s, numofDbEntry:%d , index=%d", option_seq, fp_data->device_name, local_db.db_num, local_db.index); | ||||
|  | ||||
| 	if (local_db.db_num < MAX_DHCP_FINGERPRINT_LOCAL_DB) | ||||
| 		local_db.db_num++; | ||||
|  | ||||
| 	local_db.index++; | ||||
| 	if (local_db.index >= MAX_DHCP_FINGERPRINT_LOCAL_DB) | ||||
| 		local_db.index = 0; | ||||
|  | ||||
| 	return true; | ||||
|  | ||||
| db_lookup_exit: | ||||
| 	fclose(fp); | ||||
| 	free(line); | ||||
| 	return false; | ||||
|  | ||||
| } | ||||
| @@ -2,21 +2,10 @@ | ||||
|  | ||||
| #include "netifd.h" | ||||
| #include "inet_conf.h" | ||||
| #include "dhcp_fingerprint.h" | ||||
| #include "ovsdb_sync.h" | ||||
| #include "json_util.h" | ||||
|  | ||||
| /* | ||||
|  * WAR: Never populate DHCP_leased_IP with duplicate MAC entries, even if they | ||||
|  * exists in /tmp/dhcp.leases. In case there are two entries with the same MAC | ||||
|  * address, update DHCP_leased_IP with the most recent one. | ||||
|  */ | ||||
| #define WAR_LEASE_UNIQUE_MAC | ||||
|  | ||||
| // Defines | ||||
| #define MODULE_ID LOG_MODULE_ID_MAIN | ||||
|  | ||||
|  | ||||
| #if defined(WAR_LEASE_UNIQUE_MAC) | ||||
| #include "ds_tree.h" | ||||
| #include "synclist.h" | ||||
|  | ||||
| @@ -24,6 +13,7 @@ | ||||
| struct dhcp_lease_node | ||||
| { | ||||
| 	struct osn_dhcp_server_lease    dl_lease;   /* Lease data */ | ||||
| 	dhcp_fp_data_t                  dl_fp_data; /* Fingerprint decode results */ | ||||
| 	bool                            dl_sync;    /* Present on synclist */ | ||||
| 	bool                            dl_updated; /* Update pending */ | ||||
| 	ds_tree_node_t                  dl_tnode;   /* tree node */ | ||||
| @@ -38,7 +28,8 @@ static ds_key_cmp_t osn_dhcp_server_lease_cmp; | ||||
| static bool __netifd_dhcp_lease_notify( | ||||
| 		void *data, | ||||
| 		bool released, | ||||
| 		struct osn_dhcp_server_lease *dl); | ||||
| 		struct osn_dhcp_server_lease *dl, | ||||
| 		dhcp_fp_data_t *fp_data); | ||||
|  | ||||
| /* ds_tree comparator */ | ||||
| int osn_dhcp_server_lease_cmp(void *_a, void *_b) | ||||
| @@ -78,7 +69,7 @@ void *osn_dhcp_server_lease_sync(synclist_t *sync, void *_old, void *_new) | ||||
| 		pnew->dl_sync = true; | ||||
|  | ||||
| 		/* Call the original lease handler */ | ||||
| 		__netifd_dhcp_lease_notify(dhcp_lease_synclist_data, false, &pnew->dl_lease); | ||||
| 		__netifd_dhcp_lease_notify(dhcp_lease_synclist_data, false, &pnew->dl_lease, &pnew->dl_fp_data); | ||||
|  | ||||
| 		return _new; | ||||
| 	} | ||||
| @@ -86,7 +77,7 @@ void *osn_dhcp_server_lease_sync(synclist_t *sync, void *_old, void *_new) | ||||
| 		pold->dl_sync = false; | ||||
|  | ||||
| 		/* Call the original lease handler */ | ||||
| 		__netifd_dhcp_lease_notify(dhcp_lease_synclist_data, true, &pold->dl_lease); | ||||
| 		__netifd_dhcp_lease_notify(dhcp_lease_synclist_data, true, &pold->dl_lease, &pold->dl_fp_data); | ||||
|  | ||||
| 		/* Element removal */ | ||||
| 		return NULL; | ||||
| @@ -103,7 +94,7 @@ void *osn_dhcp_server_lease_sync(synclist_t *sync, void *_old, void *_new) | ||||
| 	 */ | ||||
| 	if (pold->dl_updated) { | ||||
| 		pold->dl_updated = false; | ||||
| 		__netifd_dhcp_lease_notify(dhcp_lease_synclist_data, false, &pold->dl_lease); | ||||
| 		__netifd_dhcp_lease_notify(dhcp_lease_synclist_data, false, &pold->dl_lease, &pold->dl_fp_data); | ||||
| 	} | ||||
|  | ||||
| 	return pold; | ||||
| @@ -155,6 +146,7 @@ bool netifd_dhcp_lease_notify( | ||||
| 	else if (node == NULL) { | ||||
| 		node = calloc(1, sizeof(struct dhcp_lease_node)); | ||||
| 		node->dl_lease = *dl; | ||||
| 		dhcp_fp_db_lookup(&node->dl_fp_data, dl->dl_fingerprint); | ||||
| 		ds_tree_insert(&dhcp_lease_list, node, &node->dl_lease); | ||||
| 	} | ||||
| 	else { | ||||
| @@ -181,17 +173,9 @@ bool netifd_dhcp_lease_notify( | ||||
| bool __netifd_dhcp_lease_notify( | ||||
| 		void *data, | ||||
| 		bool released, | ||||
| 		struct osn_dhcp_server_lease *dl) | ||||
| 		struct osn_dhcp_server_lease *dl, | ||||
| 		dhcp_fp_data_t *fp_data) | ||||
|  | ||||
| #else | ||||
| /* | ||||
|  * This callback is called by libinet whenever a new DHCP lease is detected. | ||||
|  */ | ||||
| bool netifd_dhcp_lease_notify( | ||||
| 		void *data, | ||||
| 		bool released, | ||||
| 		struct osn_dhcp_server_lease *dl) | ||||
| #endif | ||||
| { | ||||
| 	(void)data; | ||||
|  | ||||
| @@ -242,6 +226,18 @@ bool netifd_dhcp_lease_notify( | ||||
| 	sdl.secondary_dns_exists = true; | ||||
| 	snprintf(sdl.secondary_dns, sizeof(sdl.secondary_dns), PRI_osn_ip_addr, FMT_osn_ip_addr(dl->dl_secondarydns)); | ||||
|  | ||||
| 	sdl.db_status_exists = true; | ||||
| 	sdl.db_status = fp_data->db_status; | ||||
|  | ||||
| 	sdl.device_name_exists = true; | ||||
| 	strscpy(sdl.device_name, fp_data->device_name, sizeof(sdl.device_name)); | ||||
|  | ||||
| 	sdl.device_type_exists = true; | ||||
| 	sdl.device_type = fp_data->device_type; | ||||
|  | ||||
| 	sdl.manuf_id_exists = true; | ||||
| 	sdl.manuf_id = fp_data->manuf_id; | ||||
|  | ||||
| 	/* A lease time of 0 indicates that this entry should be deleted */ | ||||
| 	sdl.lease_time_exists = true; | ||||
| 	if (released) { | ||||
|   | ||||
| @@ -12,6 +12,7 @@ UNIT_SRC    += src/main.c | ||||
| UNIT_SRC    += src/dhcp_lease.c | ||||
| UNIT_SRC    += src/inet_iface.c | ||||
| UNIT_SRC    += src/inet_conf.c | ||||
| UNIT_SRC    += src/dhcp_fingerprint.c | ||||
|  | ||||
| UNIT_CFLAGS := -I$(UNIT_PATH)/inc | ||||
| UNIT_CFLAGS += -Isrc/lib/common/inc/ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user