mirror of
				https://git.kernel.org/pub/scm/network/wireless/iwd.git
				synced 2025-10-30 20:37:26 +01:00 
			
		
		
		
	eapol: Add eapol_frame_watch_add / remove
Allow other files to receive EAPoL frames on specified interfaces.
This commit is contained in:
		
							parent
							
								
									509324666c
								
							
						
					
					
						commit
						f05c3c30d1
					
				| @ -113,6 +113,7 @@ monitor_iwmon_SOURCES = monitor/main.c linux/nl80211.h \ | ||||
| 					src/mpdu.h src/mpdu.c \
 | ||||
| 					src/util.h src/util.c \
 | ||||
| 					src/crypto.h src/crypto.c \
 | ||||
| 					src/watchlist.h src/watchlist.c \
 | ||||
| 					src/eapol.h src/eapol.c \
 | ||||
| 					src/handshake.h src/handshake.c \
 | ||||
| 					src/eap.h src/eap.c \
 | ||||
| @ -150,6 +151,7 @@ endif | ||||
| unit_test_eap_sim_SOURCES = unit/test-eap-sim.c \
 | ||||
| 		src/crypto.h src/crypto.c src/simutil.h src/simutil.c \
 | ||||
| 		src/ie.h src/ie.c \
 | ||||
| 		src/watchlist.h src/watchlist.c \
 | ||||
| 		src/eapol.h src/eapol.c \
 | ||||
| 		src/handshake.h src/handshake.c \
 | ||||
| 		src/eap.h src/eap.c \
 | ||||
| @ -205,6 +207,7 @@ unit_test_mpdu_LDADD = ell/libell-internal.la | ||||
| unit_test_eapol_SOURCES = unit/test-eapol.c \
 | ||||
| 				src/crypto.h src/crypto.c \
 | ||||
| 				src/ie.h src/ie.c \
 | ||||
| 				src/watchlist.h src/watchlist.c \
 | ||||
| 				src/eapol.h src/eapol.c \
 | ||||
| 				src/handshake.h src/handshake.c \
 | ||||
| 				src/eap.h src/eap.c \
 | ||||
| @ -223,6 +226,7 @@ unit_test_ssid_security_LDADD = ell/libell-internal.la | ||||
| unit_test_wsc_SOURCES = unit/test-wsc.c src/wscutil.h src/wscutil.c \
 | ||||
| 				src/crypto.h src/crypto.c \
 | ||||
| 				src/ie.h src/ie.c \
 | ||||
| 				src/watchlist.h src/watchlist.c \
 | ||||
| 				src/eapol.h src/eapol.c \
 | ||||
| 				src/handshake.h src/handshake.c \
 | ||||
| 				src/eap.h src/eap.c \
 | ||||
|  | ||||
							
								
								
									
										62
									
								
								src/eapol.c
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/eapol.c
									
									
									
									
									
								
							| @ -42,9 +42,11 @@ | ||||
| #include "mpdu.h" | ||||
| #include "eap.h" | ||||
| #include "handshake.h" | ||||
| #include "watchlist.h" | ||||
| 
 | ||||
| struct l_queue *state_machines; | ||||
| struct l_queue *preauths; | ||||
| struct watchlist frame_watches; | ||||
| 
 | ||||
| eapol_deauthenticate_func_t deauthenticate = NULL; | ||||
| eapol_rekey_offload_func_t rekey_offload = NULL; | ||||
| @ -53,6 +55,8 @@ static struct l_io *pae_io; | ||||
| eapol_tx_packet_func_t tx_packet = NULL; | ||||
| void *tx_user_data; | ||||
| 
 | ||||
| uint32_t next_frame_watch_id; | ||||
| 
 | ||||
| /*
 | ||||
|  * BPF filter to match skb->dev->type == 1 (ARPHRD_ETHER) and | ||||
|  * match skb->protocol == 0x888e (PAE) or 0x88c7 (preauthentication). | ||||
| @ -1747,6 +1751,41 @@ eap_error: | ||||
| 			(int) sm->handshake->ifindex); | ||||
| } | ||||
| 
 | ||||
| struct eapol_frame_watch { | ||||
| 	uint32_t ifindex; | ||||
| 	struct watchlist_item super; | ||||
| }; | ||||
| 
 | ||||
| static void eapol_frame_watch_free(struct watchlist_item *item) | ||||
| { | ||||
| 	struct eapol_frame_watch *efw = | ||||
| 		container_of(item, struct eapol_frame_watch, super); | ||||
| 
 | ||||
| 	l_free(efw); | ||||
| } | ||||
| 
 | ||||
| static const struct watchlist_ops eapol_frame_watch_ops = { | ||||
| 	.item_free = eapol_frame_watch_free, | ||||
| }; | ||||
| 
 | ||||
| uint32_t eapol_frame_watch_add(uint32_t ifindex, | ||||
| 				eapol_frame_watch_func_t handler, | ||||
| 				void *user_data) | ||||
| { | ||||
| 	struct eapol_frame_watch *efw; | ||||
| 
 | ||||
| 	efw = l_new(struct eapol_frame_watch, 1); | ||||
| 	efw->ifindex = ifindex; | ||||
| 
 | ||||
| 	return watchlist_link(&frame_watches, &efw->super, | ||||
| 				handler, user_data, NULL); | ||||
| } | ||||
| 
 | ||||
| bool eapol_frame_watch_remove(uint32_t id) | ||||
| { | ||||
| 	return watchlist_remove(&frame_watches, id); | ||||
| } | ||||
| 
 | ||||
| struct preauth_sm { | ||||
| 	uint32_t ifindex; | ||||
| 	uint8_t aa[6]; | ||||
| @ -1962,7 +2001,15 @@ void eapol_preauth_cancel(uint32_t ifindex) | ||||
| 				L_UINT_TO_PTR(ifindex)); | ||||
| } | ||||
| 
 | ||||
| void __eapol_rx_packet(uint32_t ifindex, const uint8_t *aa, uint16_t proto, | ||||
| static bool eapol_frame_watch_match_ifindex(const void *a, const void *b) | ||||
| { | ||||
| 	struct eapol_frame_watch *efw = | ||||
| 		container_of(a, struct eapol_frame_watch, super); | ||||
| 
 | ||||
| 	return efw->ifindex == L_PTR_TO_UINT(b); | ||||
| } | ||||
| 
 | ||||
| void __eapol_rx_packet(uint32_t ifindex, const uint8_t *src, uint16_t proto, | ||||
| 					const uint8_t *frame, size_t len) | ||||
| { | ||||
| 	const struct eapol_header *eh; | ||||
| @ -1984,15 +2031,21 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *aa, uint16_t proto, | ||||
| 	if (len < (size_t) 4 + L_BE16_TO_CPU(eh->packet_len)) | ||||
| 		return; | ||||
| 
 | ||||
| 	WATCHLIST_NOTIFY_MATCHES(&frame_watches, | ||||
| 					eapol_frame_watch_match_ifindex, | ||||
| 					L_UINT_TO_PTR(ifindex), | ||||
| 					eapol_frame_watch_func_t, proto, src, | ||||
| 					(const struct eapol_frame *) eh); | ||||
| 
 | ||||
| 	if (proto == ETH_P_PAE) { | ||||
| 		struct eapol_sm *sm = eapol_find_sm(ifindex, aa); | ||||
| 		struct eapol_sm *sm = eapol_find_sm(ifindex, src); | ||||
| 
 | ||||
| 		if (!sm) | ||||
| 			return; | ||||
| 
 | ||||
| 		eapol_rx_packet(sm, frame, len); | ||||
| 	} else if (proto == 0x88c7) { | ||||
| 		struct preauth_sm *sm = preauth_find_sm(ifindex, aa); | ||||
| 		struct preauth_sm *sm = preauth_find_sm(ifindex, src); | ||||
| 
 | ||||
| 		if (!sm) | ||||
| 			return; | ||||
| @ -2005,6 +2058,7 @@ bool eapol_init() | ||||
| { | ||||
| 	state_machines = l_queue_new(); | ||||
| 	preauths = l_queue_new(); | ||||
| 	watchlist_init(&frame_watches, &eapol_frame_watch_ops); | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| @ -2021,5 +2075,7 @@ bool eapol_exit() | ||||
| 
 | ||||
| 	l_queue_destroy(preauths, preauth_sm_destroy); | ||||
| 
 | ||||
| 	watchlist_destroy(&frame_watches); | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| @ -124,6 +124,9 @@ typedef void (*eapol_deauthenticate_func_t)(uint32_t ifindex, const uint8_t *aa, | ||||
| 						void *user_data); | ||||
| typedef void (*eapol_preauth_cb_t)(const uint8_t *pmk, void *user_data); | ||||
| typedef void (*eapol_preauth_destroy_func_t)(void *user_data); | ||||
| typedef void (*eapol_frame_watch_func_t)(uint16_t proto, const uint8_t *from, | ||||
| 						const struct eapol_frame *frame, | ||||
| 						void *user_data); | ||||
| 
 | ||||
| bool eapol_calculate_mic(const uint8_t *kck, const struct eapol_key *frame, | ||||
| 				uint8_t *mic); | ||||
| @ -190,6 +193,11 @@ void eapol_sm_set_event_func(struct eapol_sm *sm, eapol_sm_event_func_t func); | ||||
| void eapol_register(struct eapol_sm *sm); | ||||
| void eapol_start(struct eapol_sm *sm); | ||||
| 
 | ||||
| uint32_t eapol_frame_watch_add(uint32_t ifindex, | ||||
| 				eapol_frame_watch_func_t handler, | ||||
| 				void *user_data); | ||||
| bool eapol_frame_watch_remove(uint32_t id); | ||||
| 
 | ||||
| struct preauth_sm *eapol_preauth_start(const uint8_t *aa, | ||||
| 					const struct handshake_state *hs, | ||||
| 					eapol_preauth_cb_t cb, void *user_data, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Andrew Zaborowski
						Andrew Zaborowski