Пример #1
0
uint8_t dhcp_get_ip()
{

    uint8_t sockid = SOCKET_INVALID;

    // First get a socket
    sockid = udp_open(DHCP_CLIENT_PORT);
    if (sockid == SOCKET_INVALID)
        return 1;
    dhcp_send_packet(sockid, DHCP_DISCOVER);
    if (dhcp_read_packet(sockid) != DHCP_OFFER)
        return 2;
    dhcp_send_packet(sockid, DHCP_REQUEST);
    if (dhcp_read_packet(sockid) != DHCP_ACK)
        return 3;
    
    // Finally close the socket
    udp_close(sockid);
    return 0;
}
Пример #2
0
int dhcp_request(uip_ipaddr_t *next_ip, uip_ipaddr_t *server_ip,
		 const char **bootfile)
{
	DhcpPacket out, in;
	uint8_t byte;
	uint8_t *options;
	int remaining;
	uint8_t requested[] = { DhcpTagSubnetMask, DhcpTagDefaultRouter };
	assert(DhcpMaxPacketSize >= DhcpMinPacketSize);
	uint16_t max_size = htonw(DhcpMaxPacketSize);
	uint8_t client_id[1 + sizeof(uip_ethaddr)];
	client_id[0] = DhcpEthernet;
	memcpy(client_id + 1, &uip_ethaddr, sizeof(uip_ethaddr));

	// Set up the UDP connection.
	uip_ipaddr_t addr;
	uip_ipaddr(&addr, 255,255,255,255);
	struct uip_udp_conn *conn = uip_udp_new(&addr, htonw(DhcpServerPort));
	if (!conn) {
		printf("Failed to set up UDP connection.\n");
		return 1;
	}
	uip_udp_bind(conn, htonw(DhcpClientPort));

	// Send a DHCP discover packet.
	dhcp_prep_packet(&out, rand());
	options = out.options;
	remaining = sizeof(out.options);
	byte = DhcpDiscover;
	dhcp_add_option(&options, DhcpTagMessageType, &byte, sizeof(byte),
			&remaining);
	dhcp_add_option(&options, DhcpTagClientIdentifier, client_id,
			sizeof(client_id), &remaining);
	dhcp_add_option(&options, DhcpTagParameterRequestList, requested,
			sizeof(requested), &remaining);
	dhcp_add_option(&options, DhcpTagMaximumDhcpMessageSize,
			&max_size, sizeof(max_size), &remaining);
	dhcp_add_option(&options, DhcpTagEndOfList, NULL, 0, &remaining);
	dhcp_send_packet(conn, "DHCP discover", &out, &in);

	// Extract the DHCP server id.
	uint32_t server_id;
	if (dhcp_process_options(&in, OptionOverloadNone, &dhcp_get_server,
				 &server_id)) {
		printf("Failed to extract server id.\n");
		return 1;
	}

	// We got an offer. Request it.
	dhcp_state = DhcpRequesting;
	dhcp_prep_packet(&out, rand());
	options = out.options;
	remaining = sizeof(out.options);
	byte = DhcpRequest;
	dhcp_add_option(&options, DhcpTagMessageType, &byte, sizeof(byte),
			&remaining);
	dhcp_add_option(&options, DhcpTagClientIdentifier, client_id,
			sizeof(client_id), &remaining);
	dhcp_add_option(&options, DhcpTagRequestedIpAddress, &in.your_ip,
			sizeof(in.your_ip), &remaining);
	dhcp_add_option(&options, DhcpTagParameterRequestList, requested,
			sizeof(requested), &remaining);
	dhcp_add_option(&options, DhcpTagMaximumDhcpMessageSize,
			&max_size, sizeof(max_size), &remaining);
	dhcp_add_option(&options, DhcpTagServerIdentifier,
			&server_id, sizeof(server_id), &remaining);
	dhcp_add_option(&options, DhcpTagEndOfList, NULL, 0, &remaining);
	dhcp_send_packet(conn, "DHCP request", &out, &in);

	DhcpMessageType type;
	if (dhcp_process_options(&in, OptionOverloadNone, &dhcp_get_type,
				 &type)) {
		printf("Failed to extract message type.\n");
		dhcp_state = DhcpInit;
		return 1;
	}
	if (type == DhcpNak) {
		printf("DHCP request nak-ed by the server.\n");
		dhcp_state = DhcpInit;
		return 1;
	}

	// The server acked, completing the transaction.
	dhcp_state = DhcpBound;
	uip_udp_remove(conn);

	// Apply the settings.
	if (dhcp_process_options(&in, OptionOverloadNone,
				 &dhcp_apply_options, NULL)) {
		dhcp_state = DhcpInit;
		return 1;
	}

	int bootfile_size = sizeof(in.bootfile_name) + 1;
	char *file = xmalloc(bootfile_size);
	file[bootfile_size - 1] = 0;
	memcpy(file, in.bootfile_name, sizeof(in.bootfile_name));
	*bootfile = file;
	uip_ipaddr(next_ip, in.server_ip >> 0, in.server_ip >> 8,
			    in.server_ip >> 16, in.server_ip >> 24);

	uip_ipaddr(server_ip, server_id >> 0, server_id >> 8,
			      server_id >> 16, server_id >> 24);

	uip_ipaddr_t my_ip;
	uip_ipaddr(&my_ip, in.your_ip >> 0, in.your_ip >> 8,
			   in.your_ip >> 16, in.your_ip >> 24);
	uip_sethostaddr(&my_ip);

	return 0;
}