ipconfigd_threads.h [plain text]
#ifndef _S_IPCONFIGD_THREADS_H
#define _S_IPCONFIGD_THREADS_H
#include <mach/boolean.h>
#include "dhcp.h"
#include "ipconfig_types.h"
#include "globals.h"
#include "bootp_session.h"
#include "arp_session.h"
#include "timer.h"
#include "interfaces.h"
#include <TargetConditionals.h>
typedef enum {
IFEventID_start_e = 0,
IFEventID_stop_e,
IFEventID_timeout_e,
IFEventID_media_e,
IFEventID_data_e,
IFEventID_arp_e,
IFEventID_change_e,
IFEventID_renew_e,
IFEventID_arp_collision_e,
IFEventID_sleep_e,
IFEventID_wake_e,
IFEventID_power_off_e,
IFEventID_last_e,
} IFEventID_t;
static __inline__ const char *
IFEventID_names(IFEventID_t evid)
{
static const char * names[] = {
"START",
"STOP",
"TIMEOUT",
"MEDIA",
"DATA",
"ARP",
"CHANGE",
"RENEW",
"ARP COLLISION",
"SLEEP",
"WAKE",
"POWER OFF",
};
if (evid < IFEventID_start_e || evid >= IFEventID_last_e)
return ("<unknown event>");
return (names[evid]);
}
typedef struct ServiceState Service_t;
typedef struct IFState IFState_t;
typedef ipconfig_status_t (ipconfig_func_t)(Service_t * service_p,
IFEventID_t evid, void * evdata);
struct completion_results {
ipconfig_status_t status;
void * pkt;
int pkt_size;
dhcpol_t options;
boolean_t ready;
char * msg;
};
typedef struct {
boolean_t valid;
boolean_t active;
} link_status_t;
#define RIFLAGS_IADDR_VALID (uint32_t)0x1
#define RIFLAGS_HWADDR_VALID (uint32_t)0x2
#define RIFLAGS_ARP_VERIFIED (uint32_t)0x4
#define RIFLAGS_ALL_VALID (RIFLAGS_IADDR_VALID | RIFLAGS_HWADDR_VALID | RIFLAGS_ARP_VERIFIED)
typedef struct {
uint32_t flags;
struct in_addr iaddr;
uint8_t hwaddr[MAX_LINK_ADDR_LEN];
} router_info_t;
struct ServiceState {
IFState_t * ifstate;
ipconfig_method_t method;
ip_addr_mask_t requested_ip;
void * serviceID;
void * parent_serviceID;
void * child_serviceID;
#if ! TARGET_OS_EMBEDDED
void * user_notification;
void * user_rls;
#endif
struct completion_results published;
inet_addrinfo_t info;
router_info_t router;
boolean_t free_in_progress;
boolean_t is_dynamic;
void * private;
};
struct IFState {
interface_t * if_p;
CFStringRef ifname;
link_status_t link;
dynarray_t services;
Service_t * linklocal_service_p;
boolean_t startup_ready;
boolean_t free_in_progress;
boolean_t netboot;
CFStringRef ssid;
};
struct saved_pkt {
dhcpol_t options;
uint8_t pkt[1500];
int pkt_size;
unsigned rating;
boolean_t is_dhcp;
struct in_addr our_ip;
struct in_addr server_ip;
};
typedef struct {
ipconfig_method_data_t * data;
unsigned int data_len;
} config_data_t;
typedef struct {
config_data_t config;
} start_event_data_t;
typedef struct {
config_data_t config;
boolean_t needs_stop;
} change_event_data_t;
typedef struct {
struct in_addr ip_addr;
void * hwaddr;
int hwlen;
} arp_collision_data_t;
static __inline__ boolean_t
ip_valid(struct in_addr ip)
{
if (ip.s_addr == 0
|| ip.s_addr == INADDR_BROADCAST)
return (FALSE);
return (TRUE);
}
extern ipconfig_status_t
validate_method_data_addresses(config_data_t * cfg, ipconfig_method_t method,
const char * ifname);
extern unsigned
count_params(dhcpol_t * options, const uint8_t * tags, int size);
extern void *
find_option_with_length(dhcpol_t * options, dhcptag_t tag, int min_length);
extern char * computer_name();
static __inline__ IFState_t *
service_ifstate(Service_t * service_p)
{
return (service_p->ifstate);
}
static __inline__ void
service_set_requested_ip_addr(Service_t * service_p, struct in_addr ip)
{
service_p->requested_ip.addr = ip;
return;
}
static __inline__ struct in_addr
service_requested_ip_addr(Service_t * service_p)
{
return (service_p->requested_ip.addr);
}
static __inline__ struct in_addr *
service_requested_ip_addr_ptr(Service_t * service_p)
{
return (&service_p->requested_ip.addr);
}
static __inline__ void
service_set_requested_ip_mask(Service_t * service_p, struct in_addr mask)
{
service_p->requested_ip.mask = mask;
return;
}
static __inline__ struct in_addr
service_requested_ip_mask(Service_t * service_p)
{
return (service_p->requested_ip.mask);
}
int
service_enable_autoaddr(Service_t * service_p);
int
service_disable_autoaddr(Service_t * service_p);
int
service_set_address(Service_t * service_p, struct in_addr ip,
struct in_addr mask, struct in_addr broadcast);
int
service_remove_address(Service_t * service_p);
void
service_publish_success(Service_t * service_p, void * pkt, int pkt_size);
void
service_publish_success2(Service_t * service_p, void * pkt, int pkt_size,
absolute_time_t start);
void
service_publish_failure(Service_t * service_p,
ipconfig_status_t status, char * msg);
void
service_publish_failure_sync(Service_t * service_p, ipconfig_status_t status,
char * msg, boolean_t sync);
#if TARGET_OS_EMBEDDED
static __inline__ void
service_report_conflict(Service_t * service_p, struct in_addr * ip,
const void * hwaddr, struct in_addr * server)
{
}
static __inline__ void
service_remove_conflict(Service_t * service_p)
{
}
#else
void
service_report_conflict(Service_t * service_p, struct in_addr * ip,
const void * hwaddr, struct in_addr * server);
void
service_remove_conflict(Service_t * service_p);
#endif
static __inline__ interface_t *
service_interface(Service_t * service_p)
{
return (service_p->ifstate->if_p);
}
static __inline__ link_status_t *
service_link_status(Service_t * service_p)
{
return (&service_p->ifstate->link);
}
static __inline__ bool
service_is_address_set(Service_t * service_p)
{
return (service_p->info.addr.s_addr
== service_requested_ip_addr_ptr(service_p)->s_addr);
}
Service_t *
service_parent_service(Service_t * service_p);
boolean_t
service_should_do_router_arp(Service_t * service_p);
void
linklocal_service_change(Service_t * parent_service_p, boolean_t no_allocate);
void
linklocal_set_needs_attention(void);
static __inline__ boolean_t
service_router_is_hwaddr_valid(Service_t * service_p)
{
return ((service_p->router.flags & RIFLAGS_HWADDR_VALID) != 0);
}
static __inline__ void
service_router_set_hwaddr_valid(Service_t * service_p)
{
service_p->router.flags |= RIFLAGS_HWADDR_VALID;
return;
}
static __inline__ void
service_router_clear_hwaddr_valid(Service_t * service_p)
{
service_p->router.flags &= ~RIFLAGS_HWADDR_VALID;
return;
}
static __inline__ boolean_t
service_router_is_iaddr_valid(Service_t * service_p)
{
return ((service_p->router.flags & RIFLAGS_IADDR_VALID) != 0);
}
static __inline__ void
service_router_set_iaddr_valid(Service_t * service_p)
{
service_p->router.flags |= RIFLAGS_IADDR_VALID;
return;
}
static __inline__ void
service_router_clear_iaddr_valid(Service_t * service_p)
{
service_p->router.flags &= ~RIFLAGS_IADDR_VALID;
return;
}
static __inline__ boolean_t
service_router_is_arp_verified(Service_t * service_p)
{
return ((service_p->router.flags & RIFLAGS_ARP_VERIFIED) != 0);
}
static __inline__ void
service_router_set_arp_verified(Service_t * service_p)
{
service_p->router.flags |= RIFLAGS_ARP_VERIFIED;
return;
}
static __inline__ void
service_router_clear_arp_verified(Service_t * service_p)
{
service_p->router.flags &= ~RIFLAGS_ARP_VERIFIED;
return;
}
static __inline__ void
service_router_clear(Service_t * service_p)
{
service_p->router.flags = 0;
return;
}
static __inline__ u_char *
service_router_hwaddr(Service_t * service_p)
{
return (service_p->router.hwaddr);
}
static __inline__ int
service_router_hwaddr_size(Service_t * service_p)
{
return (sizeof(service_p->router.hwaddr));
}
static __inline__ struct in_addr
service_router_iaddr(Service_t * service_p)
{
return (service_p->router.iaddr);
}
static __inline__ void
service_router_set_iaddr(Service_t * service_p, struct in_addr iaddr)
{
service_p->router.iaddr = iaddr;
return;
}
static __inline__ boolean_t
service_router_all_valid(Service_t * service_p)
{
return ((service_p->router.flags & RIFLAGS_ALL_VALID) == RIFLAGS_ALL_VALID);
}
static __inline__ void
service_router_set_all_valid(Service_t * service_p)
{
service_p->router.flags = RIFLAGS_ALL_VALID;
return;
}
typedef enum {
router_arp_status_success_e = 0,
router_arp_status_no_response_e = 1,
router_arp_status_failed_e = 99,
} router_arp_status_t;
typedef void (service_resolve_router_callback_t)(Service_t * service_p,
router_arp_status_t status);
boolean_t
service_resolve_router(Service_t * service_p, arp_client_t * arp,
service_resolve_router_callback_t * callback_func,
struct in_addr our_ip);
boolean_t
service_update_router_address(Service_t * service_p,
struct saved_pkt * saved_p);
struct in_addr *
get_router_from_options(dhcpol_t * options_p, struct in_addr our_ip);
ipconfig_status_t
bootp_thread(Service_t * service_p, IFEventID_t evid, void * evdata);
ipconfig_status_t
dhcp_thread(Service_t * service_p, IFEventID_t evid, void * evdata);
ipconfig_status_t
manual_thread(Service_t * service_p, IFEventID_t evid, void * evdata);
ipconfig_status_t
inform_thread(Service_t * service_p, IFEventID_t evid, void * evdata);
ipconfig_status_t
linklocal_thread(Service_t * service_p, IFEventID_t evid, void * evdata);
ipconfig_status_t
failover_thread(Service_t * service_p, IFEventID_t evid, void * evdata);
void
netboot_addresses(struct in_addr * ip, struct in_addr * server_ip);
boolean_t
woke_from_hibernation(void);
typedef struct {
bool tentative;
bool nak;
struct in_addr our_ip;
absolute_time_t lease_start;
dhcp_lease_time_t lease_length;
struct in_addr router_ip;
uint8_t router_hwaddr[MAX_LINK_ADDR_LEN];
int router_hwaddr_length;
int pkt_length;
uint8_t pkt[1];
} DHCPLease, * DHCPLeaseRef;
typedef dynarray_t DHCPLeaseList, * DHCPLeaseListRef;
void
DHCPLeaseSetNAK(DHCPLeaseRef lease_p, int nak);
void
DHCPLeaseListInit(DHCPLeaseListRef list_p);
void
DHCPLeaseListFree(DHCPLeaseListRef list_p);
void
DHCPLeaseListClear(DHCPLeaseListRef list_p,
const char * ifname,
uint8_t cid_type, const void * cid, int cid_length);
void
DHCPLeaseListRemoveLease(DHCPLeaseListRef list_p,
struct in_addr our_ip,
struct in_addr router_ip,
const uint8_t * router_hwaddr,
int router_hwaddr_length);
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_length);
arp_address_info_t *
DHCPLeaseListCopyARPAddressInfo(DHCPLeaseListRef list_p, bool tentative_ok,
int * ret_count);
void
DHCPLeaseListWrite(DHCPLeaseListRef list_p,
const char * ifname,
uint8_t cid_type, const void * cid, int cid_length);
void
DHCPLeaseListRead(DHCPLeaseListRef list_p,
const char * ifname,
uint8_t cid_type, const void * cid, int cid_length);
int
DHCPLeaseListFindLease(DHCPLeaseListRef list_p, struct in_addr our_ip,
struct in_addr router_ip,
const uint8_t * router_hwaddr, int router_hwaddr_length);
static __inline__ int
DHCPLeaseListCount(DHCPLeaseListRef list_p)
{
return (dynarray_count(list_p));
}
static __inline__ DHCPLeaseRef
DHCPLeaseListElement(DHCPLeaseListRef list_p, int i)
{
return (dynarray_element(list_p, i));
}
void
DHCPLeaseListRemoveAllButLastLease(DHCPLeaseListRef list_p);
void
dhcp_set_default_parameters(uint8_t * params, int n_params);
void
dhcp_set_additional_parameters(uint8_t * params, int n_params);
void
dhcp_get_lease_from_options(dhcpol_t * options, dhcp_lease_time_t * lease,
dhcp_lease_time_t * t1, dhcp_lease_time_t * t2);
bool
dhcp_parameter_is_ok(uint8_t param);
extern bootp_session_t * G_bootp_session;
extern arp_session_t * G_arp_session;
#endif _S_IPCONFIGD_THREADS_H