Esempio n. 1
0
void dhcp_ack()
{
	if (next_state != ACK) {
		fprintf(err, "State is not ACK!\n");
		return;
	}
	
	struct dhcp_packet *packet = malloc(sizeof(struct dhcp_packet));
	memset(packet, 0, sizeof(struct dhcp_packet));
	int valid = 0;
	while (!valid) {
		int len = recv_packet((char*)packet, sizeof(struct dhcp_packet));
		if (len < 0) {/* timeout */
			free_socket();
			if (timeout_count--) {
				next_state = REQUEST;
				dhcp_request();
				return;
			} else {
				if (renew) {
					fprintf(err, "Failed to renew, try to re-allocate\n");
					timeout_count = TIMEOUT_RETRY_TIMES;
					next_state = DISCOVER;
					dhcp_discover();
					return;
				} else {
					//fprintf(err, "give up...\n");
					//exit(0);
					fprintf(err, "Error in dhcp_ack, sleep 60s...\n");
					sleep(60);
					timeout_count = TIMEOUT_RETRY_TIMES;
					next_state = DISCOVER;
					dhcp_discover();
					return;
				}
			}
		}
		valid = check_packet(packet);
	}
	process_lease(&ack_lease, packet);
		
	free(packet);
	free_socket();
	
	configure_interface(&ack_lease);
}
Esempio n. 2
0
void dhcp_offer()
{
	if (next_state != OFFER) {
		fprintf(err, "State is not OFFER!\n");
		return;
	}
	
	struct dhcp_packet *packet = malloc(sizeof(struct dhcp_packet));
	memset(packet, 0, sizeof(struct dhcp_packet));
	int valid = 0;
	while (!valid) {
		int len = recv_packet((char*)packet, sizeof(struct dhcp_packet));
		if (len < 0) {/* timeout */
			free_socket();
			if (timeout_count--) {
				next_state = DISCOVER;
				dhcp_discover();
				return;
			} else {
				//fprintf(err, "give up...\n");
				//exit(0);
				fprintf(err, "Error in dhcp_offer, sleep 60s...\n");
				sleep(60);
				timeout_count = TIMEOUT_RETRY_TIMES;
				next_state = DISCOVER;
				dhcp_discover();
				return;
			}
		}
		valid = check_packet(packet);
	}
	process_lease(&offer_lease, packet);
		
	free(packet);
	free_socket();
	
	timeout_count = TIMEOUT_RETRY_TIMES;
	next_state = REQUEST;
	dhcp_request();
}
Esempio n. 3
0
File: dhcp.c Progetto: NieHao/R7000
void load_dhcp(char *file, char *suffix, time_t now, char *hostname)
{
  struct crec *spares;
  time_t ttd, tts;
#ifdef HAVE_FILE_SYSTEM
  struct in_addr host_address;
  char token[MAXTOK], *dot;
  FILE *fp = fopen (file, "r");
  
  if (!fp)
    {
      syslog (LOG_ERR, "failed to load %s: %m", file);
      return;
    }
  
  syslog (LOG_INFO, "reading %s", file);
#endif

  /* remove all existing DHCP cache entries onto temp. freelist */
  spares = cache_clear_dhcp();
  
#ifdef HAVE_FILE_SYSTEM
  while ((next_token(token, MAXTOK, fp)))
    {
      if (strcmp(token, "lease") == 0)
        {
          hostname[0] = '\0';
	  ttd = tts = (time_t)(-1);

          if (next_token(token, MAXTOK, fp) && 
	      inet_pton(AF_INET, token, &host_address))
            {
              if (next_token(token, MAXTOK, fp) && *token == '{')
                {
                  while (next_token(token, MAXTOK, fp) && *token != '}')
                    {
                      if ((strcmp(token, "client-hostname") == 0) ||
			  (strcmp(token, "hostname") == 0))
			{
			  next_token(hostname, MAXDNAME, fp);
			  canonicalise(hostname);
			}
                      else if ((strcmp(token, "ends") == 0) ||
			       (strcmp(token, "starts") == 0))
                        {
                          struct tm lease_time;
			  int is_ends = (strcmp(token, "ends") == 0);
			  if (next_token(token, MAXTOK, fp) &&  /* skip weekday */
			      next_token(token, MAXTOK, fp) &&  /* Get date from lease file */
			      sscanf (token, "%d/%d/%d", 
				      &lease_time.tm_year,
				      &lease_time.tm_mon,
				      &lease_time.tm_mday) == 3 &&
			      next_token(token, MAXTOK, fp) &&
			      sscanf (token, "%d:%d:%d:", 
				      &lease_time.tm_hour,
				      &lease_time.tm_min, 
				      &lease_time.tm_sec) == 3)
			    {
			      /* There doesn't seem to be a universally available library function
				 which converts broken-down _GMT_ time to seconds-in-epoch.
				 The following was borrowed from ISC dhcpd sources, where
                                 it is noted that it might not be entirely accurate for odd seconds.
				 Since we're trying to get the same answer as dhcpd, that's just
				 fine here. */
			      static int months [11] = { 31, 59, 90, 120, 151, 181,
							 212, 243, 273, 304, 334 };
			      time_t time = ((((((365 * (lease_time.tm_year - 1970) + /* Days in years since '70 */
						  (lease_time.tm_year - 1969) / 4 +   /* Leap days since '70 */
						  (lease_time.tm_mon > 1                /* Days in months this year */
						   ? months [lease_time.tm_mon - 2]
						   : 0) +
						  (lease_time.tm_mon > 2 &&         /* Leap day this year */
						   !((lease_time.tm_year - 1972) & 3)) +
						  lease_time.tm_mday - 1) * 24) +   /* Day of month */
						lease_time.tm_hour) * 60) +
					      lease_time.tm_min) * 60) + lease_time.tm_sec;
			      if (is_ends)
				ttd = time;
			      else
				tts = time;			    }
                        }
		    }
		  
		  /* missing info? */
		  if (!*hostname)
		    continue;
		  if (ttd == (time_t)(-1))
		    continue;
		  
		  /* infinite lease to is represented by -1 */
		  /* This makes is to the lease file as 
		     start time one less than end time. */
		  /* We use -1 as infinite in ttd */
		  if ((tts != -1) && (ttd == tts - 1))
		    ttd = (time_t)(-1);
		  else if (ttd < now)
		    continue;

		  dot = strchr(hostname, '.');
		  if (suffix)
		    { 
		      if (dot) 
			{ /* suffix and lease has ending: must match */
			  if (strcmp(dot+1, suffix) != 0)
			    syslog(LOG_WARNING, 
				   "Ignoring DHCP lease for %s because it has an illegal domain part", hostname);
			  else
			    process_lease(&spares, hostname, host_address, ttd, F_REVERSE);
			}
		      else
			{ /* suffix exists but lease has no ending - add lease and lease.suffix */
			  process_lease(&spares, hostname, host_address, ttd, 0);
			  strncat(hostname, ".", MAXDNAME);
			  strncat(hostname, suffix, MAXDNAME);
			  hostname[MAXDNAME-1] = 0; /* in case strncat hit limit */
			  /* Make FQDN canonical for reverse lookups */
			  process_lease(&spares, hostname, host_address, ttd, F_REVERSE);
			}
		    }
		  else
		    { /* no suffix */
		      if (dot) /* no lease ending allowed */
			syslog(LOG_WARNING, 
			       "Ignoring DHCP lease for %s because it has a domain part", hostname);
		      else
			process_lease(&spares, hostname, host_address, ttd, F_REVERSE);
		    }
		}
	    }
	}
    }
  fclose(fp);
#else
#endif

  /* free any still-unused cache structs */
  while (spares)
    { 
      struct crec *tmp = spares->next;
      safe_free(spares);
      spares = tmp;
    }
}