Beispiel #1
0
/*
 * Parse a DHCP response packet
 * Returns:
 * 0 = Unexpected packet, not parsed
 * 2 = DHCPOFFER (from dhcp_proto.h)
 * 5 = DHCPACK
 * 6 = DHCPNACK
 */
static int dhcp_parse(struct netdev *dev, struct bootp_hdr *hdr,
		      uint8_t *exts, int extlen)
{
	uint8_t type = 0;
	uint32_t serverid = INADDR_NONE;
	int ret = 0;

	if (extlen >= 4 && exts[0] == 99 && exts[1] == 130 &&
	    exts[2] == 83 && exts[3] == 99) {
		uint8_t *ext;

		for (ext = exts + 4; ext - exts < extlen;) {
			uint8_t len, *opt = ext++;
			if (*opt == 0)
				continue;

			len = *ext++;

			ext += len;

			if (*opt == 53)
				type = opt[2];
			if (*opt == 54)
				memcpy(&serverid, opt + 2, 4);
		}
	}

	switch (type) {
	case DHCPOFFER:
		ret = bootp_parse(dev, hdr, exts, extlen) ? DHCPOFFER : 0;
		if (ret == DHCPOFFER && serverid != INADDR_NONE)
			dev->serverid = serverid;
		dprintf("\n   dhcp offer\n");
		break;

	case DHCPACK:
		ret = bootp_parse(dev, hdr, exts, extlen) ? DHCPACK : 0;
		dprintf("\n   dhcp ack\n");
		break;

	case DHCPNAK:
		ret = DHCPNAK;
		dprintf("\n   dhcp nak\n");
		break;
	}
	return ret;
}
Beispiel #2
0
/*
 * Parse a DHCP response packet
 * Returns:
 * 0 = Unexpected packet, not parsed
 * 2 = DHCPOFFER (from dhcp_proto.h)
 * 5 = DHCPACK
 * 6 = DHCPNACK
 */
static int dhcp_parse(struct netdev *dev, struct bootp_hdr *hdr,
		      uint8_t *exts, int extlen)
{
	uint8_t type = 0;
	uint32_t serverid = INADDR_NONE;
	uint32_t leasetime = 0;
	int ret = 0;

	if (extlen >= 4 && exts[0] == 99 && exts[1] == 130 &&
	    exts[2] == 83 && exts[3] == 99) {
		uint8_t *ext;

		for (ext = exts + 4; ext - exts < extlen;) {
			int len;
			uint8_t opt = *ext++;

			if (opt == 0)
				continue;
			else if (opt == 255)
				break;

			if (ext - exts >= extlen)
				break;
			len = *ext++;

			if (ext - exts + len > extlen)
				break;
			switch (opt) {
			case 51:	/* IP Address Lease Time */
				if (len == 4)
					leasetime = ntohl(*(uint32_t *)ext);
				break;
			case 53:	/* DHCP Message Type */
				if (len == 1)
					type = *ext;
				break;
			case 54:	/* Server Identifier */
				if (len == 4)
					memcpy(&serverid, ext, 4);
				break;
			}
			ext += len;
		}
	}

	switch (type) {
	case DHCPOFFER:
		ret = bootp_parse(dev, hdr, exts, extlen) ? DHCPOFFER : 0;
		if (ret == DHCPOFFER && serverid != INADDR_NONE)
			dev->serverid = serverid;
		dprintf("\n   dhcp offer\n");
		break;

	case DHCPACK:
		dev->dhcpleasetime = leasetime;
		ret = bootp_parse(dev, hdr, exts, extlen) ? DHCPACK : 0;
		dprintf("\n   dhcp ack\n");
		break;

	case DHCPNAK:
		ret = DHCPNAK;
		dprintf("\n   dhcp nak\n");
		break;
	}
	return ret;
}