예제 #1
0
파일: DHCPLease.c 프로젝트: aosm/bootp
/* 
 * Function: DHCPLeaseListWrite
 *
 * Purpose:
 *   Write the last DHCP lease in the list for the given interface/client_id.
 *   We only save the last (current) lease.  See the comments for 
 *   DHCPLeaseListRead above for more information.
 */
void
DHCPLeaseListWrite(DHCPLeaseListRef list_p,
		   const char * ifname,
		   uint8_t cid_type, const void * cid, int cid_length)
{
    int			count;
    char		filename[PATH_MAX];
    CFDictionaryRef	lease_dict;
    DHCPLeaseRef	lease_p;
    
    if (DHCPLeaseListGetPath(ifname, cid_type, cid, cid_length,
			     filename, sizeof(filename)) == FALSE) {
	return;
    }
    DHCPLeaseListRemoveStaleLeases(list_p);
    count = dynarray_count(list_p);
    if (count == 0) {
	unlink(filename);
	return;
    }
    lease_p = dynarray_element(list_p, count - 1);
    lease_dict = DHCPLeaseCopyDictionary(lease_p);
    if (my_CFPropertyListWriteFile(lease_dict, filename, 0644) < 0) {
	/*
	 * An ENOENT error is expected on a read-only filesystem.  All 
	 * other errors should be reported.
	 */
	if (errno != ENOENT) {
	    my_log(LOG_ERR, "my_CFPropertyListWriteFile(%s) failed, %s", 
		   filename, strerror(errno));
	}
    }
    my_CFRelease(&lease_dict);
    return;
}
예제 #2
0
파일: DHCPLease.c 프로젝트: aosm/bootp
/*
 * Function: DHCPLeaseListRemoveStaleLeases
 * Purpose:
 *   Scans the list of leases removing any that are no longer valid.
 */
static void
DHCPLeaseListRemoveStaleLeases(DHCPLeaseListRef list_p)
{
    int				count;
    absolute_time_t 		current_time;
    int				i;

    count = dynarray_count(list_p);
    if (count == 0) {
	return;
    }
    current_time = timer_current_secs();
    i = 0;
    while (i < count) {
	DHCPLeaseRef	lease_p = dynarray_element(list_p, i);

	/* check the lease expiration */
	if (lease_p->lease_length != DHCP_INFINITE_LEASE
	    && current_time >= (lease_p->lease_start + lease_p->lease_length)) {
	    /* lease is expired */
	    if (G_IPConfiguration_verbose) {
		my_log(LOG_DEBUG, "Removing Stale Lease "
		       IP_FORMAT " Router " IP_FORMAT,
		       IP_LIST(&lease_p->our_ip),
		       IP_LIST(&lease_p->router_ip));
	    }
	    dynarray_free_element(list_p, i);
	    count--;
	}
	else {
	    i++;
	}
    }
    return;
}
예제 #3
0
STATIC RTADVSocketRef
RTADVSocketFind(int if_index)
{
    int 			i;

    for (i = 0; i < dynarray_count(&S_globals->sockets); i++) {
	interface_t *		if_p;
	RTADVSocketRef		sock;

	sock = dynarray_element(&S_globals->sockets, i);
	if_p = RTADVSocketGetInterface(sock);
	if (if_index == if_link_index(if_p)) {
	    return (sock);
	}
    }
    return (NULL);
}
static void
DHCPv6SocketDemux(int if_index, const DHCPv6PacketRef pkt, int pkt_len)
{
    DHCPv6SocketReceiveData	data;
    DHCPv6OptionErrorString 	err;
    int 			i;

    if (pkt_len < DHCPV6_PACKET_HEADER_LENGTH) {
	return;
    }
    data.pkt = pkt;
    data.pkt_len = pkt_len;
    data.options = DHCPv6OptionListCreateWithPacket(pkt, pkt_len, &err);
    if (data.options == NULL) {
	my_log(LOG_NOTICE, "DHCPv6Socket: options parse failed, %s",
	       err.str);
	return;
    }
    for (i = 0; i < dynarray_count(&S_globals->sockets); i++) {
	DHCPv6SocketRef	client;

	client = dynarray_element(&S_globals->sockets, i);
	if (if_index != if_link_index(DHCPv6SocketGetInterface(client))) {
	    continue;
	}
	if (S_verbose) {
	    CFMutableStringRef	str;
	    
	    str = CFStringCreateMutable(NULL, 0);
	    DHCPv6PacketPrintToString(str, pkt, pkt_len);
	    if (data.options != NULL) {
		DHCPv6OptionListPrintToString(str, data.options);
	    }
	    my_log(-LOG_DEBUG, "[%s] Receive %@", 
		   if_name(DHCPv6SocketGetInterface(client)), str);
	    CFRelease(str);
	}
	if (client->receive_func != NULL) {
	    (*client->receive_func)(client->receive_arg1, client->receive_arg2,
				    &data);
	}
    }
    DHCPv6OptionListRelease(&data.options);
    return;
}
예제 #5
0
파일: DHCPLease.c 프로젝트: aosm/bootp
/*
 * Function: DHCPLeaseListFindLease
 * Purpose:
 *   Find a lease corresponding to the supplied information.
 */
int
DHCPLeaseListFindLease(DHCPLeaseListRef list_p, struct in_addr our_ip,
		       struct in_addr router_ip,
		       const uint8_t * router_hwaddr, int router_hwaddr_length)
{
    int			count;
    int			i;
    bool		private_ip = ip_is_private(our_ip);

    count = dynarray_count(list_p);
    for (i = 0; i < count; i++) {
	DHCPLeaseRef	lease_p = dynarray_element(list_p, i);

	if (lease_p->our_ip.s_addr != our_ip.s_addr) {
	    /* IP doesn't match */
	    continue;
	}
	if (private_ip == FALSE) {
	    /* lease for public IP is unique */
	    return (i);
	}
	if (lease_p->router_ip.s_addr != router_ip.s_addr) {
	    /* router IP doesn't match (or one is set the other isn't)*/
	    continue;
	}
	if (router_ip.s_addr == 0) {
	    /* found lease with no router information */
	    return (i);
	}
	if (lease_p->router_hwaddr_length != router_hwaddr_length) {
	    /* one has router hwaddr, other doesn't */
	    continue;
	}
	if (router_hwaddr == NULL || router_hwaddr_length == 0) {
	    /* found lease with router IP but no router hwaddr */
	    return (i);
	}
	if (bcmp(lease_p->router_hwaddr, router_hwaddr, router_hwaddr_length)
	    == 0) {
	    /* exact match on IP, router IP, router hwaddr */
	    return (i);
	}
    }
    return (-1);
}
interface_t *
ifl_find_ip(interface_list_t * list_p, struct in_addr iaddr)
{
    int 	i;

    for (i = 0; i < list_p->count; i++) {
	interface_t * if_p = list_p->list + i;
	int j;

	for (j = 0; j < dynarray_count(&if_p->inet); j++) {
	    inet_addrinfo_t *	info;

	    info = dynarray_element(&if_p->inet, j);
	    if (info->addr.s_addr == iaddr.s_addr)
		return (if_p);
	}
    }
    return (NULL);
}
예제 #7
0
파일: DHCPLease.c 프로젝트: aosm/bootp
static void
DHCPLeaseListLog(DHCPLeaseListRef list_p)
{
    int			count;
    int			i;
    CFMutableStringRef	str;
	
    str = CFStringCreateMutable(NULL, 0);
    count = dynarray_count(list_p);
    for (i = 0; i < count; i++) {
	DHCPLeaseRef	lease_p = dynarray_element(list_p, i);

	STRING_APPEND(str, "\n%d. ", i + 1);
	DHCPLeasePrintToString(str, lease_p);
    }
    my_log(~LOG_DEBUG, "DHCPLeaseList has %d element(s)%@", count, str);
    CFRelease(str);
    return;
}
interface_t *
ifl_find_subnet(interface_list_t * list_p, struct in_addr iaddr)
{
    int 	i;
    u_long	addr_hl = iptohl(iaddr);

    for (i = 0; i < list_p->count; i++) {
	interface_t * if_p = list_p->list + i;
	int j;

	for (j = 0; j < dynarray_count(&if_p->inet); j++) {
	    inet_addrinfo_t *	info = dynarray_element(&if_p->inet, j);
	    u_long 		ifnetaddr_hl = iptohl(info->netaddr);
	    u_long 		ifmask_hl = iptohl(info->mask);

	    if ((addr_hl & ifmask_hl) == ifnetaddr_hl)
		return (if_p);
	}
    }
    return (NULL);
}
예제 #9
0
파일: DHCPLease.c 프로젝트: aosm/bootp
/* 
 * Function: DHCPLeaseListUpdateLease
 *
 * Purpose:
 *   Update the lease entry for the given lease in the in-memory lease database.
 */
void
DHCPLeaseListUpdateLease(DHCPLeaseListRef list_p, struct in_addr our_ip,
			 struct in_addr router_ip,
			 const uint8_t * router_hwaddr,
			 int router_hwaddr_length,
			 absolute_time_t lease_start,
			 dhcp_lease_time_t lease_length,
			 const uint8_t * pkt, int pkt_size,
			 CFStringRef ssid)
{
    int			count;
    int			i;
    DHCPLeaseRef	lease_p;
    boolean_t		private_ip = ip_is_private(our_ip);

    lease_p = DHCPLeaseCreate(our_ip, router_ip,
			      router_hwaddr, router_hwaddr_length,
			      lease_start, lease_length, pkt, pkt_size,
			      ssid);
    /* scan lease list to eliminate NAK'd, incomplete, and duplicate leases */
    count = dynarray_count(list_p);
    for (i = 0; i < count; i++) {
	DHCPLeaseRef	scan_p = dynarray_element(list_p, i);

	if (DHCPLeaseShouldBeRemoved(scan_p, lease_p, private_ip)) {
	    dynarray_free_element(list_p, i);
	    i--;
	    count--;
	}
    }
    dynarray_add(list_p, lease_p);
    if (G_IPConfiguration_verbose) {
	my_log(LOG_DEBUG, "Saved lease for " IP_FORMAT,
	       IP_LIST(&lease_p->our_ip));
	if (G_IPConfiguration_verbose) {
	    DHCPLeaseListLog(list_p);
	}
    }
    return;
}
inet_addrinfo_t *
if_inet_addr_at(interface_t * if_p, int i)
{
    return (dynarray_element(&if_p->inet, i));
}
예제 #11
0
파일: DHCPLease.c 프로젝트: aosm/bootp
/*
 * Function: DHCPLeaseListCopyARPAddressInfo
 * Purpose:
 *   Returns a list of arp_address_info_t's corresponding to each
 *   discoverable lease.
 */
arp_address_info_t *
DHCPLeaseListCopyARPAddressInfo(DHCPLeaseListRef list_p,
				CFStringRef ssid,
				absolute_time_t * start_time_threshold_p,
				bool tentative_ok,
				int * ret_count)
{
    int				arp_info_count;
    arp_address_info_t *	arp_info_p;
    int				count;
    int				i;
    arp_address_info_t *	info_p;

    DHCPLeaseListRemoveStaleLeases(list_p);
    count = dynarray_count(list_p);
    if (count == 0) {
	*ret_count = 0;
	return (NULL);
    }
    arp_info_p = (arp_address_info_t *)malloc(sizeof(*arp_info_p) * count);
    arp_info_count = 0;
    info_p = arp_info_p;
    for (i = 0; i < count; i++) {
	DHCPLeaseRef	lease_p = dynarray_element(list_p, i);

	if (ssid != NULL) {
	    if (lease_p->ssid == NULL || !CFEqual(lease_p->ssid, ssid)) {
		if (G_IPConfiguration_verbose) {
		    my_log(LOG_DEBUG,
			   "ignoring lease with SSID %@",
			   lease_p->ssid);
		    continue;
		}
	    }
	    
	}
	if (lease_p->router_ip.s_addr == 0
	    || lease_p->router_hwaddr_length == 0) {
	    /* can't use this with ARP discovery */
	    if (G_IPConfiguration_verbose) {
		my_log(LOG_DEBUG, "ignoring lease for " IP_FORMAT,
		       IP_LIST(&lease_p->our_ip));
	    }
	    continue;
	}
	if (lease_p->tentative && tentative_ok == FALSE) {
	    /* ignore tentative lease */
	    continue;
	}
	if (start_time_threshold_p != NULL
	    && lease_p->lease_start < *start_time_threshold_p) {
	    if (G_IPConfiguration_verbose) {
		my_log(LOG_DEBUG, 
		       "start time on lease " IP_FORMAT " too old (%ld < %ld)",
		       IP_LIST(&lease_p->our_ip),
		       lease_p->lease_start, *start_time_threshold_p);
	    }
	    continue;
	}
	info_p->sender_ip = lease_p->our_ip;
	info_p->target_ip = lease_p->router_ip;
	bcopy(lease_p->router_hwaddr, info_p->target_hardware,
	      lease_p->router_hwaddr_length);
	arp_info_count++;
	info_p++;
    }
    if (arp_info_count == 0) {
	free(arp_info_p);
	arp_info_p = NULL;
    }
    *ret_count = arp_info_count;
    return (arp_info_p);
}