コード例 #1
0
ファイル: dhcp.c プロジェクト: dafyddcrosby/L4OS
// something has timed out, handle this
static void dhcp_timeout(struct dhcp_state *state)
{
  DEBUGF(DHCP_DEBUG, ("dhcp_timeout()\n"));
  if ((state->state == DHCP_BACKING_OFF) || (state->state == DHCP_SELECTING))
  {
    DEBUGF(DHCP_DEBUG, ("dhcp_timeout(): restarting discovery\n"));
    dhcp_discover(state);
  }
  else if (state->state == DHCP_REQUESTING)
  {
    DEBUGF(DHCP_DEBUG, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n"));
    if (state->tries <= 5)
    {
      dhcp_select(state);
    }
    else
    {
      DEBUGF(DHCP_DEBUG, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
      dhcp_release(state);
      dhcp_discover(state);
    }
  }
  else if (state->state == DHCP_CHECKING)
  {
    DEBUGF(DHCP_DEBUG, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
    if (state->tries <= 1)
    {
      dhcp_check(state);
    }
    // no ARP replies on the offered address,
    // looks like the IP address is indeed free
    else
    {
      dhcp_bind(state);
    }
  }
  else if (state->state == DHCP_RENEWING)
  {
    DEBUGF(DHCP_DEBUG, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));
    dhcp_renew(state);
  }
  else if (state->state == DHCP_REBINDING)
  {
    DEBUGF(DHCP_DEBUG, ("dhcp_timeout(): REBINDING, DHCP request timed out\n"));
    if (state->tries <= 8)
    {
      dhcp_rebind(state);
    }
    else
    {
      DEBUGF(DHCP_DEBUG, ("dhcp_timeout(): REBINDING, release, restart\n"));
      dhcp_release(state);
      dhcp_discover(state);
    }
  }
}
コード例 #2
0
ファイル: dhcp.c プロジェクト: dafyddcrosby/L4OS
static void dhcp_handle_offer(struct dhcp_state *state)
{
  u8_t *option_ptr = dhcp_get_option_ptr(state, DHCP_OPTION_SERVER_ID);
  if (option_ptr != NULL)
  {
    state->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
    DEBUGF(DHCP_DEBUG, ("dhcp_handle_offer(): server 0x%08lx\n", state->server_ip_addr.addr));
    /* remember offered address */
    ip_addr_set(&state->offered_ip_addr, (struct ip_addr *)&state->msg_in->yiaddr);
    DEBUGF(DHCP_DEBUG, ("dhcp_handle_offer(): offer for 0x%08lx\n", state->offered_ip_addr.addr));
    dhcp_select(state);
  }
  else
  {
    //dhcp_start(restart);
  }
}
コード例 #3
0
ファイル: in_dhcp.c プロジェクト: Prajna/xnu
/*
 * Function: dhcp_init
 * Purpose:
 *   Start in the DHCP INIT state sending DISCOVER's.  When we get OFFER's,
 *   try to select one of them by sending a REQUEST and waiting for an ACK.
 */
static int
dhcp_init(struct dhcp_context * context)
{
    struct timeval		current_time;
    int				error = 0;
    uint32_t			lease_option = htonl(SUGGESTED_LEASE_LENGTH);
    dhcpoa_t *			options_p;
    struct dhcp_packet *	request;
    int				request_size;
    int				retry;
    int				wait_ticks;

    /* remember the time we started */
    microtime(&context->start_time);
    current_time = context->start_time;
    
    request = dhcp_context_request(context);
    options_p = &context->request_options;

 retry:
    /* format a DHCP DISCOVER packet */
    make_dhcp_request(&request->dhcp, DHCP_PAYLOAD_MIN,
		      dhcp_msgtype_discover_e,
		      link_address(context->dl_p), ARPHRD_ETHER,
		      link_address_length(context->dl_p), 
		      options_p);
    /* add the requested lease time */
    dhcpoa_add(options_p, dhcptag_lease_time_e,
	       sizeof(lease_option), &lease_option);
    dhcpoa_add(options_p, dhcptag_end_e, 0, 0);
    request_size = sizeof(*request) + RFC_MAGIC_SIZE 
	+ dhcpoa_used(options_p);
    if (request_size < (int)sizeof(struct bootp_packet)) {
	/* pad out to BOOTP-sized packet */
	request_size = sizeof(struct bootp_packet);
    }
    init_dhcp_packet_header(request, request_size);

    wait_ticks = INITIAL_WAIT_SECS * hz;
    for (retry = 0; retry < context->max_try; retry++) {
	/* Send the request */
	printf("dhcp: sending DISCOVER\n");
	request->dhcp.dp_secs 
	    = htons((u_short)(current_time.tv_sec 
			      - context->start_time.tv_sec));
	request->dhcp.dp_xid = htonl(context->xid);
#ifdef RANDOM_IP_ID
	request->ip.ip_id = ip_randomid();
#else
	request->ip.ip_id = htons(ip_id++);
#endif
	error = send_packet(context->ifp, request, request_size);
	if (error != 0) {
	    printf("dhcp: send_packet failed with %d\n", error);
	    goto failed;
	}
	wait_ticks += random_range(-RAND_TICKS, RAND_TICKS);
	dprintf(("dhcp: waiting %d ticks\n", wait_ticks));
	error = dhcp_get_offer(context, wait_ticks);
	if (error == 0) {
	    /* send a REQUEST */
	    error = dhcp_select(context);
	    if (error == 0) {
		/* we're done !*/
		goto done;
	    }
	    if (error != EPROTO && error != ETIMEDOUT) {
		/* fatal error */ 
		dprintf(("dhcp: dhcp_select failed %d\n", error));
		goto failed;
	    }
	    /* wait 10 seconds, and try again */
	    printf("dhcp: trying again in 10 seconds\n");
	    tsleep(&error, PRIBIO, "dhcp_init", 10 * hz);
	    context->xid++;
	    goto retry;
	}
	else if (error != EWOULDBLOCK) {
	    dprintf(("dhcp: failed to receive packets: %d\n", error));
	    goto failed;
	}
	wait_ticks *= 2;
	if (wait_ticks > (MAX_WAIT_SECS * hz))
	    wait_ticks = MAX_WAIT_SECS * hz;
	microtime(&current_time);
    }
    error = ETIMEDOUT;
    goto failed;
    
 done:
    error = 0;

 failed:
    return (error);
}