#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
unsigned long debug_trace_level = 0; /* DEBUG_ULTRA */
-time_t cur_time;
-time_t default_lease_time = 43200; /* 12 hours... */
char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
char *path_dhclient_db = NULL;
struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
struct in_addr inaddr_any;
struct sockaddr_in sockaddr_broadcast;
-unsigned long old_default_route = 0;
/*
* ASSERT_STATE() does nothing now; it used to be
int unknown_ok = 1;
int routefd;
-struct interface_info *ifi = NULL;
-
void usage(void);
int check_option(struct client_lease *l, int option);
int ipv4addrs(char * buf);
int
main(int argc, char *argv[])
{
- int i = 0;
ApiInit();
AdapterInit();
PipeInit();
tzset();
- time(&cur_time);
memset(&sockaddr_broadcast, 0, sizeof(sockaddr_broadcast));
sockaddr_broadcast.sin_family = AF_INET;
DH_DbgPrint(MID_TRACE,("DHCP Service Started\n"));
- read_client_conf();
-
- if (!interface_link_status(ifi->name)) {
- DH_DbgPrint(MID_TRACE,("%s: no link ", ifi->name));
- Sleep(1000);
- while (!interface_link_status(ifi->name)) {
- DH_DbgPrint(MID_TRACE,("."));
- if (++i > 10) {
- DH_DbgPrint(MID_TRACE,("Giving up for now on adapter [%s]\n", ifi->name));
- }
- Sleep(1000);
- }
- DH_DbgPrint(MID_TRACE,("Got link on [%s]\n", ifi->name));
- }
-
- DH_DbgPrint(MID_TRACE,("Discover Interfaces\n"));
-
- /* If no adapters were found, just idle for now ... If any show up,
- * then we'll start it later */
- if( ifi ) {
- /* set up the interface */
- discover_interfaces(ifi);
-
- DH_DbgPrint
- (MID_TRACE,
- ("Setting init state and restarting interface %p\n",ifi));
- }
-
bootp_packet_handler = do_packet;
DH_DbgPrint(MID_TRACE,("Going into dispatch()\n"));
flags. */
make_request(ip, ip->client->active);
ip->client->destination = iaddr_broadcast;
- ip->client->first_sending = cur_time;
+ time(&ip->client->first_sending);
ip->client->interval = ip->client->config->initial_interval;
/* Zap the medium list... */
ip->client->xid = ip->client->packet.xid;
ip->client->destination = iaddr_broadcast;
ip->client->state = S_SELECTING;
- ip->client->first_sending = cur_time;
+ time(&ip->client->first_sending);
ip->client->interval = ip->client->config->initial_interval;
/* Add an immediate timeout to cause the first DHCPDISCOVER packet
{
struct interface_info *ip = ipp;
struct client_lease *lp, *next, *picked;
+ time_t cur_time;
ASSERT_STATE(state, S_SELECTING);
+ time(&cur_time);
+
/* Cancel state_selecting and send_discover timeouts, since either
one could have got us here. */
cancel_timeout(state_selecting, ip);
{
struct interface_info *ip = packet->interface;
struct client_lease *lease;
+ time_t cur_time;
+
+ time(&cur_time);
/* If we're not receptive to an offer right now, or if the offer
has an unrecognizable transaction id, then just drop it. */
ip->client->new->expiry = getULong(
ip->client->new->options[DHO_DHCP_LEASE_TIME].data);
else
- ip->client->new->expiry = default_lease_time;
+ ip->client->new->expiry = DHCP_DEFAULT_LEASE_TIME;
/* A number that looks negative here is really just very large,
because the lease expiry offset is unsigned. */
if (ip->client->new->expiry < 0)
bind_lease(ip);
}
-void set_name_servers( struct client_lease *new_lease ) {
+void set_name_servers( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
+ CHAR Buffer[200] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
+ HKEY RegKey;
+
+ strcat(Buffer, Adapter->DhclientInfo.name);
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, Buffer, 0, KEY_WRITE, &RegKey ) != ERROR_SUCCESS)
+ return;
+
+
if( new_lease->options[DHO_DOMAIN_NAME_SERVERS].len ) {
- HKEY RegKey;
+
struct iaddr nameserver;
char *nsbuf;
int i, addrs =
new_lease->options[DHO_DOMAIN_NAME_SERVERS].len / sizeof(ULONG);
- /* XXX I'm setting addrs to 1 until we are ready up the chain */
- addrs = 1;
nsbuf = malloc( addrs * sizeof(IP_ADDRESS_STRING) );
- nsbuf[0] = 0;
- if( nsbuf && !RegOpenKeyEx
- ( HKEY_LOCAL_MACHINE,
- "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
- 0, KEY_WRITE, &RegKey ) ) {
+ if( nsbuf) {
+ nsbuf[0] = 0;
for( i = 0; i < addrs; i++ ) {
nameserver.len = sizeof(ULONG);
memcpy( nameserver.iabuf,
DH_DbgPrint(MID_TRACE,("Setting DhcpNameserver: %s\n", nsbuf));
- RegSetValueEx( RegKey, "DhcpNameServer", 0, REG_SZ,
- (LPBYTE)nsbuf, strlen(nsbuf) + 1);
-
+ RegSetValueExA( RegKey, "DhcpNameServer", 0, REG_SZ,
+ (LPBYTE)nsbuf, strlen(nsbuf) + 1 );
free( nsbuf );
}
+
+ } else {
+ RegDeleteValueW( RegKey, L"DhcpNameServer" );
}
+
+ RegCloseKey( RegKey );
+
}
void setup_adapter( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
+ CHAR Buffer[200] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
struct iaddr netmask;
+ HKEY hkey;
+ int i;
+ DWORD dwEnableDHCP;
+
+ strcat(Buffer, Adapter->DhclientInfo.name);
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, Buffer, 0, KEY_WRITE, &hkey) != ERROR_SUCCESS)
+ hkey = NULL;
+
if( Adapter->NteContext )
DeleteIPAddress( Adapter->NteContext );
memcpy( netmask.iabuf,
new_lease->options[DHO_SUBNET_MASK].data,
new_lease->options[DHO_SUBNET_MASK].len );
-
Status = AddIPAddress
( *((ULONG*)new_lease->address.iabuf),
*((ULONG*)netmask.iabuf),
Adapter->IfMib.dwIndex,
&Adapter->NteContext,
&Adapter->NteInstance );
+ if (hkey) {
+ RegSetValueExA(hkey, "DhcpIPAddress", 0, REG_SZ, (LPBYTE)piaddr(new_lease->address), strlen(piaddr(new_lease->address))+1);
+ Buffer[0] = '\0';
+ for(i = 0; i < new_lease->options[DHO_SUBNET_MASK].len; i++)
+ {
+ sprintf(&Buffer[strlen(Buffer)], "%u", new_lease->options[DHO_SUBNET_MASK].data[i]);
+ if (i + 1 < new_lease->options[DHO_SUBNET_MASK].len)
+ strcat(Buffer, ".");
+ }
+ RegSetValueExA(hkey, "DhcpSubnetMask", 0, REG_SZ, (LPBYTE)Buffer, strlen(Buffer)+1);
+ RegSetValueExA(hkey, "IPAddress", 0, REG_SZ, (LPBYTE)"0.0.0.0", 8);
+ RegSetValueExA(hkey, "SubnetMask", 0, REG_SZ, (LPBYTE)"0.0.0.0", 8);
+ dwEnableDHCP = 1;
+ RegSetValueExA(hkey, "EnableDHCP", 0, REG_DWORD, (LPBYTE)&dwEnableDHCP, sizeof(DWORD));
+ }
if( !NT_SUCCESS(Status) )
warning("AddIPAddress: %lx\n", Status);
}
if( new_lease->options[DHO_ROUTERS].len ) {
- MIB_IPFORWARDROW RouterMib;
NTSTATUS Status;
- RouterMib.dwForwardDest = 0; /* Default route */
- RouterMib.dwForwardMask = 0;
- RouterMib.dwForwardMetric1 = 1;
+ Adapter->RouterMib.dwForwardDest = 0; /* Default route */
+ Adapter->RouterMib.dwForwardMask = 0;
+ Adapter->RouterMib.dwForwardMetric1 = 1;
- if( old_default_route ) {
+ if( Adapter->RouterMib.dwForwardNextHop ) {
/* If we set a default route before, delete it before continuing */
- RouterMib.dwForwardDest = old_default_route;
- DeleteIpForwardEntry( &RouterMib );
+ DeleteIpForwardEntry( &Adapter->RouterMib );
}
- RouterMib.dwForwardNextHop =
+ Adapter->RouterMib.dwForwardNextHop =
*((ULONG*)new_lease->options[DHO_ROUTERS].data);
- Status = CreateIpForwardEntry( &RouterMib );
+ Status = CreateIpForwardEntry( &Adapter->RouterMib );
if( !NT_SUCCESS(Status) )
warning("CreateIpForwardEntry: %lx\n", Status);
- else
- old_default_route = RouterMib.dwForwardNextHop;
+
+ if (hkey) {
+ Buffer[0] = '\0';
+ for(i = 0; i < new_lease->options[DHO_ROUTERS].len; i++)
+ {
+ sprintf(&Buffer[strlen(Buffer)], "%u", new_lease->options[DHO_ROUTERS].data[i]);
+ if (i + 1 < new_lease->options[DHO_ROUTERS].len)
+ strcat(Buffer, ".");
+ }
+ RegSetValueExA(hkey, "DhcpDefaultGateway", 0, REG_SZ, (LPBYTE)Buffer, strlen(Buffer)+1);
+ RegSetValueExA(hkey, "DefaultGateway", 0, REG_SZ, (LPBYTE)"0.0.0.0", 8);
+ }
}
+
+ if (hkey)
+ RegCloseKey(hkey);
}
{
PDHCP_ADAPTER Adapter;
struct client_lease *new_lease = ip->client->new;
+ time_t cur_time;
+
+ time(&cur_time);
/* Remember the medium. */
ip->client->new->medium = ip->client->medium;
note("bound to %s -- renewal in %ld seconds.",
piaddr(ip->client->active->address),
- ip->client->active->renewal - cur_time);
+ (long int)(ip->client->active->renewal - cur_time));
ip->client->state = S_BOUND;
Adapter = AdapterFindInfo( ip );
if( Adapter ) setup_adapter( Adapter, new_lease );
- else warning("Could not find adapter for info %p\n", ip);
-
- set_name_servers( new_lease );
-
- reinitialize_interfaces();
+ else {
+ warning("Could not find adapter for info %p\n", ip);
+ return;
+ }
+ set_name_servers( Adapter, new_lease );
}
/*
} else
ip->client->destination = iaddr_broadcast;
- ip->client->first_sending = cur_time;
+ time(&ip->client->first_sending);
ip->client->interval = ip->client->config->initial_interval;
ip->client->state = S_RENEWING;
int arp_timeout_needed = 0, stop_selecting;
char *name = packet->options[DHO_DHCP_MESSAGE_TYPE].len ?
"DHCPOFFER" : "BOOTREPLY";
+ time_t cur_time;
+
+ time(&cur_time);
/* If we're not receptive to an offer right now, or if the offer
has an unrecognizable transaction id, then just drop it. */
{
struct interface_info *ip = ipp;
int interval, increase = 1;
+ time_t cur_time;
DH_DbgPrint(MID_TRACE,("Doing discover on interface %p\n",ip));
+ time(&cur_time);
+
/* Figure out how long it's been since we started transmitting. */
interval = cur_time - ip->client->first_sending;
note("DHCPDISCOVER on %s to %s port %d interval %ld",
ip->name, inet_ntoa(sockaddr_broadcast.sin_addr),
- ntohs(sockaddr_broadcast.sin_port), ip->client->interval);
+ ntohs(sockaddr_broadcast.sin_port), (long int)ip->client->interval);
/* Send out a packet. */
(void)send_packet(ip, &ip->client->packet, ip->client->packet_length,
struct interface_info *ip = ipp;
struct client_lease *loop = ip->client->active;
struct client_lease *lp;
+ time_t cur_time;
note("No DHCPOFFERS received.");
+ time(&cur_time);
+
/* We may not have an active lease, but we may have some
predefined leases that we can try. */
if (!ip->client->active && ip->client->leases)
ip->client->active->renewal) {
ip->client->state = S_BOUND;
note("bound: renewal in %ld seconds.",
- ip->client->active->renewal -
- cur_time);
+ (long int)(ip->client->active->renewal -
+ cur_time));
add_timeout(
ip->client->active->renewal,
state_bound, ip);
note("bound: immediate renewal.");
state_bound(ip);
}
- reinitialize_interfaces();
return;
}
struct sockaddr_in destination;
struct in_addr from;
int interval;
+ time_t cur_time;
+
+ time(&cur_time);
/* Figure out how long it's been since we started transmitting. */
interval = cur_time - ip->client->first_sending;
FILE *leaseFile;
void
-rewrite_client_leases(void)
+rewrite_client_leases(struct interface_info *ifi)
{
struct client_lease *lp;
if (!leaseFile) {
leaseFile = fopen(path_dhclient_db, "w");
if (!leaseFile)
- error("can't create %s: %m", path_dhclient_db);
+ error("can't create %s", path_dhclient_db);
} else {
fflush(leaseFile);
rewind(leaseFile);
if (!rewrite) {
if (leases_written++ > 20) {
- rewrite_client_leases();
+ rewrite_client_leases(ip);
leases_written = 0;
}
}
if (!leaseFile) { /* XXX */
leaseFile = fopen(path_dhclient_db, "w");
- if (!leaseFile)
- error("can't create %s: %m", path_dhclient_db);
+ if (!leaseFile) {
+ error("can't create %s", path_dhclient_db);
+ return;
+ }
}
fprintf(leaseFile, "lease {\n");
lease->options[i].len, 1, 1));
t = gmtime(&lease->renewal);
- fprintf(leaseFile, " renew %d %d/%d/%d %02d:%02d:%02d;\n",
- t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
- t->tm_hour, t->tm_min, t->tm_sec);
+ if (t)
+ fprintf(leaseFile, " renew %d %d/%d/%d %02d:%02d:%02d;\n",
+ t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+ t->tm_hour, t->tm_min, t->tm_sec);
t = gmtime(&lease->rebind);
- fprintf(leaseFile, " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
- t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
- t->tm_hour, t->tm_min, t->tm_sec);
+ if (t)
+ fprintf(leaseFile, " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
+ t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+ t->tm_hour, t->tm_min, t->tm_sec);
t = gmtime(&lease->expiry);
- fprintf(leaseFile, " expire %d %d/%d/%d %02d:%02d:%02d;\n",
- t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
- t->tm_hour, t->tm_min, t->tm_sec);
+ if (t)
+ fprintf(leaseFile, " expire %d %d/%d/%d %02d:%02d:%02d;\n",
+ t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+ t->tm_hour, t->tm_min, t->tm_sec);
fprintf(leaseFile, "}\n");
fflush(leaseFile);
}
sizeof(size_t) + strlen(reason);
if ((buf = buf_open(hdr.len)) == NULL)
- error("buf_open: %m");
+ return;
errs = 0;
errs += buf_add(buf, &hdr, sizeof(hdr));
errs += buf_add(buf, reason, len);
if (errs)
- error("buf_add: %m");
+ error("buf_add: %d", WSAGetLastError());
if (buf_close(privfd, buf) == -1)
- error("buf_close: %m");
+ error("buf_close: %d", WSAGetLastError());
}
void
-priv_script_init(char *reason, char *medium)
+priv_script_init(struct interface_info *ip, char *reason, char *medium)
{
- struct interface_info *ip = ifi;
-
if (ip) {
// XXX Do we need to do anything?
}
}
void
-priv_script_write_params(char *prefix, struct client_lease *lease)
+priv_script_write_params(struct interface_info *ip, char *prefix, struct client_lease *lease)
{
- struct interface_info *ip = ifi;
u_int8_t dbuf[1500];
int i, len = 0;
len = ip->client->
config->defaults[i].len +
lease->options[i].len;
- if (len > sizeof(dbuf)) {
+ if (len >= sizeof(dbuf)) {
warning("no space to %s %s",
"prepend option",
dhcp_options[i].name);
case ACTION_APPEND:
len = ip->client->
config->defaults[i].len +
- lease->options[i].len;
+ lease->options[i].len + 1;
if (len > sizeof(dbuf)) {
warning("no space to %s %s",
"append option",
config->defaults[i].data,
ip->client->
config->defaults[i].len);
- dp[len] = '\0';
+ dp[len-1] = '\0';
}
} else {
dp = ip->client->
scripttime = time(NULL);
if ((buf = buf_open(hdr.len)) == NULL)
- error("buf_open: %m");
+ return;
errs = 0;
errs += buf_add(buf, &hdr, sizeof(hdr));
}
if (errs)
- error("buf_add: %m");
+ error("buf_add: %d", WSAGetLastError());
if (buf_close(privfd, buf) == -1)
- error("buf_close: %m");
+ error("buf_close: %d", WSAGetLastError());
}
int
case DHO_HOST_NAME:
case DHO_DOMAIN_NAME:
case DHO_NIS_DOMAIN:
- if (!res_hnok(sbuf)) {
+ if (!res_hnok(sbuf))
warning("Bogus Host Name option %d: %s (%s)", option,
sbuf, opbuf);
- return (0);
- }
return (1);
case DHO_PAD:
case DHO_TIME_OFFSET:
return "<error>";
}
-#if 0
-int
-fork_privchld(int fd, int fd2)
-{
- struct pollfd pfd[1];
- int nfds;
-
- switch (fork()) {
- case -1:
- error("cannot fork");
- case 0:
- break;
- default:
- return (0);
- }
-
- setproctitle("%s [priv]", ifi->name);
-
- dup2(nullfd, STDIN_FILENO);
- dup2(nullfd, STDOUT_FILENO);
- dup2(nullfd, STDERR_FILENO);
- close(nullfd);
- close(fd2);
-
- for (;;) {
- pfd[0].fd = fd;
- pfd[0].events = POLLIN;
- if ((nfds = poll(pfd, 1, INFTIM)) == -1)
- if (errno != EINTR)
- error("poll error");
-
- if (nfds == 0 || !(pfd[0].revents & POLLIN))
- continue;
-
- dispatch_imsg(fd);
- }
-}
-#endif
\ No newline at end of file