コード例 #1
0
ファイル: main.c プロジェクト: Agochka/klibc
static void process_timeout_event(struct state *s, time_t now)
{
	int ret = 0;

	/*
	 * Is the link up?  If not, try again in 1 second.
	 */
	if (!netdev_running(s->dev)) {
		s->expire = now + 1;
		s->state = s->restart_state;
		return;
	}

	/*
	 * If we had an error, restore a sane state to
	 * restart from.
	 */
	if (s->state == DEVST_ERROR)
		s->state = s->restart_state;

	/*
	 * Now send a packet depending on our state.
	 */
	switch (s->state) {
	case DEVST_BOOTP:
		ret = bootp_send_request(s->dev);
		s->restart_state = DEVST_BOOTP;
		break;

	case DEVST_DHCPDISC:
		ret = dhcp_send_discover(s->dev);
		s->restart_state = DEVST_DHCPDISC;
		break;

	case DEVST_DHCPREQ:
		ret = dhcp_send_request(s->dev);
		s->restart_state = DEVST_DHCPDISC;
		break;
	}

	if (ret == -1) {
		s->state = DEVST_ERROR;
		s->expire = now + 10;
	} else {
		s->expire = now + s->retry_period;

		s->retry_period *= 2;
		if (s->retry_period > 60)
			s->retry_period = 60;
	}
}
コード例 #2
0
void dhcp_check_timeout(void) {
	if(retry_count < DHCP_MAX_RETRY) {
		if(next_dhcp_time < dhcp_time) {
			dhcp_time = 0;
			next_dhcp_time = dhcp_time + DHCP_WAIT_TIME;
			retry_count++;

			switch(dhcp_state) {
				case STATE_DHCP_DISCOVER: {
					dhcp_send_discover(dhcp_socket);
					break;
				}

				case STATE_DHCP_REQUEST: {
					dhcp_send_request(dhcp_socket);
					break;
				}

				case STATE_DHCP_REREQUEST: {
					dhcp_send_request(dhcp_socket);
					break;
				}

				default : {
					break;
				}
			}
		}
	} else {
		dhcp_reset_time();
		DHCP_timeout = 1;

		dhcp_send_discover(dhcp_socket);
		dhcp_state = STATE_DHCP_DISCOVER;
	}
}
コード例 #3
0
ファイル: dhcp.c プロジェクト: sli92/netcon
void dhcp_app_call(void)
{
        if(uip_newdata()) {
                switch(dhcp_s.state) {
                        case DHCP_STATE_OFFER:
                                dhcp_parse_offer();
                                break;

                        case DHCP_STATE_ACK:
                                dhcp_parse_ack();
                                break;
                }
        }

        if(uip_poll()) {
                switch(dhcp_s.state) {
                        case DHCP_STATE_BOOT_WAIT:
                                if(get_clock() > dhcp_s.dhcp_renew_time)
                                        dhcp_s.state = DHCP_STATE_DISCOVER;
                                break;

                        case DHCP_STATE_DISCOVER:
                                dhcp_send_discover();
                                break;

                        case DHCP_STATE_REQUEST:
                                dhcp_send_request();
                                break;

                        case DHCP_STATE_WAIT_RENEW:
                                if(get_clock() > dhcp_s.dhcp_renew_time)
                                        dhcp_s.state = DHCP_STATE_REQUEST;
                                break;
                }
        }
}
コード例 #4
0
ファイル: main.c プロジェクト: Agochka/klibc
/*
 * Returns:
 *  0 = Not handled, try again later
 *  1 = Handled
 */
static int process_receive_event(struct state *s, time_t now)
{
	int handled = 1;

	switch (s->state) {
	case DEVST_ERROR:
		return 0; /* Not handled */
	case DEVST_COMPLETE:
		return 0; /* Not handled as already configured */

	case DEVST_BOOTP:
		s->restart_state = DEVST_BOOTP;
		switch (bootp_recv_reply(s->dev)) {
		case -1:
			s->state = DEVST_ERROR;
			break;
		case 0:
			handled = 0;
			break;
		case 1:
			s->state = DEVST_COMPLETE;
			dprintf("\n   bootp reply\n");
			break;
		}
		break;

	case DEVST_DHCPDISC:
		s->restart_state = DEVST_DHCPDISC;
		switch (dhcp_recv_offer(s->dev)) {
		case -1:
			s->state = DEVST_ERROR;
			break;
		case 0:
			handled = 0;
			break;
		case DHCPOFFER:	/* Offer received */
			s->state = DEVST_DHCPREQ;
			dhcp_send_request(s->dev);
			break;
		}
		break;

	case DEVST_DHCPREQ:
		s->restart_state = DEVST_DHCPDISC;
		switch (dhcp_recv_ack(s->dev)) {
		case -1:	/* error */
			s->state = DEVST_ERROR;
			break;
		case 0:
			handled = 0;
			break;
		case DHCPACK:	/* ACK received */
			s->state = DEVST_COMPLETE;
			break;
		case DHCPNAK:	/* NAK received */
			s->state = DEVST_DHCPDISC;
			break;
		}
		break;

	default:
		dprintf("\n");
		handled = 0;
		break;
	}

	switch (s->state) {
	case DEVST_COMPLETE:
		complete_device(s->dev);
		break;

	case DEVST_ERROR:
		/* error occurred, try again in 10 seconds */
		s->expire = now + 10;
		break;
	}

	return handled;
}
コード例 #5
0
ファイル: main.c プロジェクト: Tikiwinkie/PJE
/* Called at the reception of a DHCP Offer packet.
   p points to the DHCP Offer
*/
void dhcp_request(FullPacket *p)
{
    dhcp_send_request(p->dhcp.xid, p->dhcp.yiaddr, ntohl(dhcp_get_option_simple(p->dhcp.options+4, OPTION_DHCP_SERVER_IDENTIFIER)), 1);
}
コード例 #6
0
ファイル: dhcp.c プロジェクト: AjayMashi/x-tier
int8_t
handle_dhcp(uint8_t * packet, int32_t packetsize) {
	struct btphdr * btph;
	struct iphdr * iph;
	dhcp_options_t opt;

	memset(&opt, 0, sizeof(dhcp_options_t));  
	btph = (struct btphdr *) packet;
	iph = (struct iphdr *) packet - sizeof(struct udphdr) -
	      sizeof(struct iphdr);
	if (btph -> op != 2)
		return -1; // it is not Boot Reply

	if(response_buffer) {
		if(packetsize <= 1720)
			memcpy(response_buffer, packet, packetsize);
		else
			memcpy(response_buffer, packet, 1720);
	}

	if (memcmp(btph -> vend, dhcp_magic, 4)) {
		// It is BootP - RFC 951
		dhcp_own_ip    = htonl(btph -> yiaddr);
		dhcp_siaddr_ip = htonl(btph -> siaddr);
		dhcp_server_ip = htonl(iph -> ip_src);

		if (strlen((char *) btph -> sname) && !dhcp_siaddr_ip) {
			strncpy((char *) dhcp_tftp_name, (char *) btph -> sname,
			        sizeof(btph -> sname));
			dhcp_tftp_name[sizeof(btph -> sname)] = 0;
		}

		if (strlen((char *) btph -> file)) {
			strncpy((char *) dhcp_filename, (char *) btph -> file, sizeof(btph -> file));
			dhcp_filename[sizeof(btph -> file)] = 0;
		}

		dhcp_state = DHCP_STATE_SUCCESS;
		return 0;
	}


	// decode options  
	if (!dhcp_decode_options(btph -> vend, packetsize -
	                         sizeof(struct btphdr) + sizeof(btph -> vend),
	                         &opt)) {
		return -1;  // can't decode options
	}

	if (opt.overload) {
		int16_t decode_res = 0;
		uint8_t options[1024]; // buffer for merged options
		uint32_t opt_len;

		// move 1-st part of options from vend field into buffer
		opt_len = packetsize - sizeof(struct btphdr) +
		          sizeof(btph -> vend) - 4;
		memcpy(options, btph -> vend, opt_len + 4);

		// add other parts
		switch (opt.overload) {
		case DHCP_OVERLOAD_FILE:
			decode_res = dhcp_merge_options(options + 4, &opt_len,
			                                btph -> file,
			                                sizeof(btph -> file));
			break;
		case DHCP_OVERLOAD_SNAME:
			decode_res = dhcp_merge_options(options + 4, &opt_len,
			                                btph -> sname,
			                                sizeof(btph -> sname));
			break;
		case DHCP_OVERLOAD_BOTH:
			decode_res = dhcp_merge_options(options + 4, &opt_len,
			                                btph -> file,
			                                sizeof(btph -> file));
			if (!decode_res)
				break;
			decode_res = dhcp_merge_options(options + 4, &opt_len,
			                                btph -> sname,
			                                sizeof(btph -> sname));
			break;
		}

		if (!decode_res)
			return -1; // bad options in sname/file fields

		// decode merged options
		if (!dhcp_decode_options(options, opt_len + 4, &opt)) {
			return -1; // can't decode options
		}
	}

	if (!opt.msg_type) {
		// It is BootP with Extensions - RFC 1497
		// retrieve conf. settings from BootP - reply
		dhcp_own_ip = htonl(btph -> yiaddr);
		dhcp_siaddr_ip = htonl(btph -> siaddr);
		if (strlen((char *) btph -> sname) && !dhcp_siaddr_ip) {
			strncpy((char *) dhcp_tftp_name, (char *) btph -> sname, sizeof(btph -> sname));
			dhcp_tftp_name[sizeof(btph -> sname)] = 0;
		}

		if (strlen((char *) btph -> file)) {
			strncpy((char *) dhcp_filename, (char *) btph -> file, sizeof(btph -> file));
			dhcp_filename[sizeof(btph -> file)] = 0;
		}

		// retrieve DHCP-server IP from IP-header
		dhcp_server_ip = iph -> htonl(ip_src);

		dhcp_state = DHCP_STATE_SUCCESS;
	}
	else {
		// It is DHCP - RFC 2131 & RFC 2132
		// opt contains parameters from server
		switch (dhcp_state) {
		case DHCP_STATE_SELECT :
			if (opt.msg_type == DHCPOFFER) {
				dhcp_own_ip = htonl(btph -> yiaddr);
				dhcp_server_ip = opt.server_ID;
				dhcp_send_request();
				dhcp_state = DHCP_STATE_REQUEST;
			}
			return 0;
		case DHCP_STATE_REQUEST :
			switch (opt.msg_type) {
			case DHCPNACK :
				dhcp_own_ip = 0;
				dhcp_server_ip = 0;
				dhcp_state = DHCP_STATE_FAULT;
				break;
			case DHCPACK :
				dhcp_own_ip = htonl(btph -> yiaddr);
				dhcp_server_ip = opt.server_ID;
				dhcp_siaddr_ip = htonl(btph -> siaddr);
				if (opt.flag[DHCP_TFTP_SERVER]) {
					strcpy((char *) dhcp_tftp_name, (char *) opt.tftp_server);
				}
				else {
					strcpy((char *) dhcp_tftp_name, "");
					if ((opt.overload != DHCP_OVERLOAD_SNAME &&
					     opt.overload != DHCP_OVERLOAD_BOTH) &&
					     !dhcp_siaddr_ip) {
						strncpy((char *) dhcp_tftp_name,
						        (char *) btph->sname,
						        sizeof(btph -> sname));
						dhcp_tftp_name[sizeof(btph->sname)] = 0;
					}
				}

				if (opt.flag[DHCP_BOOTFILE]) {
					strcpy((char *) dhcp_filename, (char *) opt.bootfile);
				}
				else {
					strcpy((char *) dhcp_filename, "");
					if (opt.overload != DHCP_OVERLOAD_FILE &&
						opt.overload != DHCP_OVERLOAD_BOTH && 
						strlen((char *) btph -> file)) {
						strncpy((char *) dhcp_filename,
						        (char *) btph->file,
						        sizeof(btph->file));
						dhcp_filename[sizeof(btph -> file)] = 0;
					}
				}

				dhcp_state = DHCP_STATE_SUCCESS;
				break;
			default:
				break; // Unused DHCP-message - do nothing
			}
			break;
		default :
			return -1; // Illegal DHCP-client state
		}
	}

	if (dhcp_state == DHCP_STATE_SUCCESS) {

		// initialize network entity with real own_ip
		// to be able to answer for foreign requests
		set_ipv4_address(dhcp_own_ip);

		/* Subnet mask */
		if (opt.flag[DHCP_MASK]) {
			/* Router */
			if (opt.flag[DHCP_ROUTER]) {
				set_ipv4_router(opt.router_IP);
				set_ipv4_netmask(opt.subnet_mask);
			}
		}

		/* DNS-server */
		if (opt.flag[DHCP_DNS]) {
			dns_init(opt.dns_IP);
		}
	}

	return 0;
}
コード例 #7
0
void dhcp_check_state(const uint8_t s) {
	if(dhcp_state == STATE_DHCP_DISCOVER && DHCP_timeout == 1) {
		DHCP_timeout = 0;
		logethw("DHCP timeout, trying again\n\r");
		return;
	}

	uint32_t len;
	uint8_t type = 0;

	if(ethernet_low_level_get_status(s) != ETH_VAL_SN_SR_SOCK_CLOSED) {
		if((len = ethernet_low_level_get_received_data_length(s)) > 0) {
			type = dhcp_parse_msg(s, len);
		}
	} else {
		dhcp_create_socket(s);
	}


	switch(dhcp_state) {
		case STATE_DHCP_DISCOVER: {
			if(type == DHCP_OFFER) {
				dhcp_reset_time();
				dhcp_send_request(s);
				dhcp_state = STATE_DHCP_REQUEST;
			} else {
				dhcp_check_timeout();
			}
			break;
		}

		case STATE_DHCP_REQUEST: {
			if(type == DHCP_ACK) {
				dhcp_reset_time();
				if(dhcp_check_leased_ip()) {
					dhcp_set_network();
					dhcp_state = STATE_DHCP_LEASED;
				} else {
					dhcp_state = STATE_DHCP_DISCOVER;
				}
			} else if(type == DHCP_NAK) {
				dhcp_reset_time();
				dhcp_state = STATE_DHCP_DISCOVER;
			} else {
				dhcp_check_timeout();
			}
			break;
		}

		case STATE_DHCP_LEASED: {
			if((lease_time.l_val != 0xffffffff) && ((lease_time.l_val/2) < dhcp_time)) {
				type = 0;
				memcpy(dhcp_old_ip, ethernet_status.ip, 4);
				dhcp_xid++;
				dhcp_send_request(s);
				dhcp_state = STATE_DHCP_REREQUEST;
				dhcp_reset_time();
			}
			break;
		}

		case STATE_DHCP_REREQUEST: {
			if(type == DHCP_ACK) {
				memcpy(dhcp_old_ip, ethernet_status.ip, 4);

				dhcp_reset_time();
				dhcp_state = STATE_DHCP_LEASED;
			} else if(type == DHCP_NAK) {
				dhcp_reset_time();
				dhcp_state = STATE_DHCP_DISCOVER;
			} else {
				dhcp_check_timeout();
			}
			break;
		}

		case STATE_DHCP_RELEASE: {
			break;
		}

		default: {
			break;
		}
	}
}