Move handling of address/netmask pairs from ifquery into library.
Signed-off-by: Maximilian Wilhelm <max@sdn.clinic>
This commit is contained in:
		
							parent
							
								
									17a410b87c
								
							
						
					
					
						commit
						02324bebd5
					
				
					 3 changed files with 56 additions and 45 deletions
				
			
		|  | @ -92,31 +92,6 @@ print_interface_dot(struct lif_dict *collection, struct lif_interface *iface, st | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline size_t | ||||
| count_set_bits(const char *netmask) | ||||
| { | ||||
| 	/* netmask set to CIDR length */ | ||||
| 	if (strchr(netmask, '.') == NULL) | ||||
| 		return strtol(netmask, NULL, 10); | ||||
| 
 | ||||
| 	size_t r = 0; | ||||
| 	struct in_addr in; | ||||
| 
 | ||||
| 	if (inet_pton(AF_INET, netmask, &in) == 0) | ||||
| 		return r; | ||||
| 
 | ||||
| 	/* take the IP, put it in host endian order, and
 | ||||
| 	 * flip it so that all the set bits are set to the right. | ||||
| 	 * then we can simply count down from 32 and right-shift | ||||
| 	 * until the bit field is all zero. | ||||
| 	 */ | ||||
| 	unsigned int bits = htonl(in.s_addr); | ||||
| 	for (bits = ~bits, r = 32; bits; bits >>= 1, r--) | ||||
| 		; | ||||
| 
 | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| print_interface_property(struct lif_interface *iface, const char *property) | ||||
| { | ||||
|  | @ -132,26 +107,10 @@ print_interface_property(struct lif_interface *iface, const char *property) | |||
| 
 | ||||
| 		if (printing_address) | ||||
| 		{ | ||||
| 			struct lif_address *addr = entry->data; | ||||
| 			size_t orig_netmask = addr->netmask; | ||||
| 
 | ||||
| 			if (!addr->netmask) | ||||
| 			{ | ||||
| 				/* if fallback netmask is not set, default to 255.255.255.0 */ | ||||
| 				addr->netmask = 24; | ||||
| 
 | ||||
| 				struct lif_dict_entry *entry = lif_dict_find(&iface->vars, "netmask"); | ||||
| 				if (entry != NULL) | ||||
| 					addr->netmask = count_set_bits(entry->data); | ||||
| 			} | ||||
| 
 | ||||
| 			char addr_buf[512]; | ||||
| 
 | ||||
| 			if (!lif_address_unparse(addr, addr_buf, sizeof addr_buf, true)) | ||||
| 			if (!lif_address_format_cidr(iface, entry, addr_buf, sizeof(addr_buf))) | ||||
| 				continue; | ||||
| 
 | ||||
| 			addr->netmask = orig_netmask; | ||||
| 
 | ||||
| 			printf("%s\n", addr_buf); | ||||
| 		} | ||||
| 		else | ||||
|  |  | |||
|  | @ -58,6 +58,57 @@ lif_address_unparse(const struct lif_address *address, char *buf, size_t buflen, | |||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static inline size_t | ||||
| count_set_bits(const char *netmask) | ||||
| { | ||||
|         /* netmask set to CIDR length */ | ||||
| 	if (strchr(netmask, '.') == NULL) | ||||
| 		return strtol(netmask, NULL, 10); | ||||
| 
 | ||||
| 	size_t r = 0; | ||||
| 	struct in_addr in; | ||||
| 
 | ||||
| 	if (inet_pton(AF_INET, netmask, &in) == 0) | ||||
| 		return r; | ||||
| 
 | ||||
| 	/* take the IP, put it in host endian order, and
 | ||||
| 	 * flip it so that all the set bits are set to the right. | ||||
| 	 * then we can simply count down from 32 and right-shift | ||||
| 	 * until the bit field is all zero. | ||||
| 	 */ | ||||
| 	unsigned int bits = htonl(in.s_addr); | ||||
| 	for (bits = ~bits, r = 32; bits; bits >>= 1, r--) | ||||
| 		; | ||||
| 
 | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| bool | ||||
| lif_address_format_cidr(struct lif_interface *iface, struct lif_dict_entry *entry, char *buf, size_t buflen) | ||||
| { | ||||
| 	struct lif_address *addr = entry->data; | ||||
| 	size_t orig_netmask = addr->netmask; | ||||
| 
 | ||||
| 	if (!addr->netmask) | ||||
| 	{ | ||||
| 		/* if netmask is not set, default to 255.255.255.0, ifupdown does so too */ | ||||
| 		addr->netmask = 24; | ||||
| 
 | ||||
| 		struct lif_dict_entry *entry = lif_dict_find(&iface->vars, "netmask"); | ||||
| 		if (entry != NULL) | ||||
| 			addr->netmask = count_set_bits(entry->data); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!lif_address_unparse(addr, buf, buflen, true)) | ||||
| 	{ | ||||
| 		addr->netmask = orig_netmask; | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	addr->netmask = orig_netmask; | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| lif_interface_init(struct lif_interface *interface, const char *ifname) | ||||
| { | ||||
|  |  | |||
|  | @ -32,9 +32,6 @@ struct lif_address { | |||
| 	int domain; | ||||
| }; | ||||
| 
 | ||||
| extern bool lif_address_parse(struct lif_address *address, const char *presentation); | ||||
| extern bool lif_address_unparse(const struct lif_address *address, char *buf, size_t buflen, bool with_netmask); | ||||
| 
 | ||||
| /*
 | ||||
|  * Interfaces are contained in a dictionary, with the interfaces mapped by | ||||
|  * interface name to their `struct lif_interface`. | ||||
|  | @ -68,6 +65,10 @@ struct lif_interface { | |||
| #define LIF_INTERFACE_COLLECTION_FOREACH_SAFE(iter, iter_next, collection) \ | ||||
| 	LIF_DICT_FOREACH_SAFE((iter), (iter_next), (collection)) | ||||
| 
 | ||||
| extern bool lif_address_parse(struct lif_address *address, const char *presentation); | ||||
| extern bool lif_address_unparse(const struct lif_address *address, char *buf, size_t buflen, bool with_netmask); | ||||
| extern bool lif_address_format_cidr(struct lif_interface *iface, struct lif_dict_entry *entry, char *buf, size_t buflen); | ||||
| 
 | ||||
| extern void lif_interface_init(struct lif_interface *interface, const char *ifname); | ||||
| extern bool lif_interface_address_add(struct lif_interface *interface, const char *address); | ||||
| extern void lif_interface_address_delete(struct lif_interface *interface, const char *address); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue