static void test_invalid_buffer_length(void) { DHCPMessage message; assert_se(dhcp_option_parse(&message, 0, NULL, NULL) == -EINVAL); assert_se(dhcp_option_parse(&message, sizeof(DHCPMessage), NULL, NULL) == -EINVAL); }
static void test_options(struct option_desc *desc) { uint8_t *options = NULL; uint8_t *file = NULL; uint8_t *sname = NULL; int optlen = 0; int filelen = 0; int snamelen = 0; int buflen = 0; _cleanup_free_ DHCPMessage *message; int res; if (desc) { file = &desc->file[0]; filelen = desc->filelen; if (!filelen) desc->filepos = -1; sname = &desc->sname[0]; snamelen = desc->snamelen; if (!snamelen) desc->snamepos = -1; options = &desc->options[0]; optlen = desc->len; desc->pos = 0; } message = create_message(options, optlen, file, filelen, sname, snamelen); buflen = sizeof(DHCPMessage) + 4 + optlen; if (!desc) { assert_se((res = dhcp_option_parse(message, buflen, test_options_cb, NULL)) == -ENOMSG); } else if (desc->success) { assert_se((res = dhcp_option_parse(message, buflen, test_options_cb, desc)) >= 0); assert_se(desc->pos == -1 && desc->filepos == -1 && desc->snamepos == -1); } else assert_se((res = dhcp_option_parse(message, buflen, test_options_cb, desc)) < 0); if (verbose) printf("DHCP type %s\n", dhcp_type(res)); }
static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover) { uint16_t udp_check = 0; uint8_t *msg_bytes = (uint8_t *)discover; int res; res = dhcp_option_parse(discover, size, check_options, NULL, NULL); assert_se(res == DHCP_DISCOVER); assert_se(msg_bytes[size - 1] == SD_DHCP_OPTION_END); xid = discover->xid; if (verbose) printf(" recv DHCP Discover 0x%08x\n", be32toh(xid)); memcpy(&test_addr_acq_offer[26], &udp_check, sizeof(udp_check)); memcpy(&test_addr_acq_offer[32], &xid, sizeof(xid)); memcpy(&test_addr_acq_offer[56], &mac_addr, ETHER_ADDR_LEN); callback_recv = test_addr_acq_recv_request; res = write(test_fd[1], test_addr_acq_offer, sizeof(test_addr_acq_offer)); assert_se(res == sizeof(test_addr_acq_offer)); if (verbose) printf(" sent DHCP Offer\n"); return 0; }
static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) { uint16_t udp_check = 0; uint8_t *msg_bytes = (uint8_t *)request; int res; res = dhcp_option_parse(request, size, check_options, NULL, NULL); assert_se(res == DHCP_REQUEST); assert_se(xid == request->xid); assert_se(msg_bytes[size - 1] == SD_DHCP_OPTION_END); if (verbose) printf(" recv DHCP Request 0x%08x\n", be32toh(xid)); memcpy(&test_addr_acq_ack[26], &udp_check, sizeof(udp_check)); memcpy(&test_addr_acq_ack[32], &xid, sizeof(xid)); memcpy(&test_addr_acq_ack[56], &mac_addr, ETHER_ADDR_LEN); callback_recv = NULL; res = write(test_fd[1], test_addr_acq_ack, sizeof(test_addr_acq_ack)); assert_se(res == sizeof(test_addr_acq_ack)); if (verbose) printf(" send DHCP Ack\n"); return 0; };
static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) { _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL; int r; r = dhcp_lease_new(&lease); if (r < 0) return r; r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease); if (r == DHCP_NAK) { log_dhcp_client(client, "NAK"); return DHCP_EVENT_NO_LEASE; } if (r != DHCP_ACK) { log_dhcp_client(client, "receieved message was not an ACK, ignoring"); return -ENOMSG; } lease->next_server = ack->siaddr; lease->address = ack->yiaddr; if (lease->address == INADDR_ANY || lease->server_address == INADDR_ANY || lease->lifetime == 0) { log_dhcp_client(client, "receieved lease lacks address, server " "address or lease lifetime, ignoring"); return -ENOMSG; } if (lease->subnet_mask == INADDR_ANY) { r = dhcp_lease_set_default_subnet_mask(lease); if (r < 0) { log_dhcp_client(client, "receieved lease lacks subnet " "mask, and a fallback one can not be " "generated, ignoring"); return -ENOMSG; } } r = DHCP_EVENT_IP_ACQUIRE; if (client->lease) { if (client->lease->address != lease->address || client->lease->subnet_mask != lease->subnet_mask || client->lease->router != lease->router) { r = DHCP_EVENT_IP_CHANGE; } client->lease = sd_dhcp_lease_unref(client->lease); } client->lease = lease; lease = NULL; log_dhcp_client(client, "ACK"); return r; }
static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp) { int res; res = dhcp_option_parse(dhcp, size, check_options, NULL, NULL); assert_se(res == DHCP_DISCOVER); if (verbose) printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp->xid)); return 0; }
static void test_cookie(void) { _cleanup_free_ DHCPMessage *message; size_t len = sizeof(DHCPMessage) + 4; uint8_t *opt; message = malloc0(len); opt = (uint8_t *)(message + 1); opt[0] = 0xff; assert_se(dhcp_option_parse(message, len, NULL, NULL) == -EINVAL); opt[0] = 99; opt[1] = 130; opt[2] = 83; opt[3] = 99; assert_se(dhcp_option_parse(message, len, NULL, NULL) == -ENOMSG); }
static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) { _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL; int r; r = dhcp_lease_new(&lease); if (r < 0) return r; r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease); if (r != DHCP_OFFER) { log_dhcp_client(client, "receieved message was not an OFFER, ignoring"); return -ENOMSG; } lease->next_server = offer->siaddr; lease->address = offer->yiaddr; if (lease->address == INADDR_ANY || lease->server_address == INADDR_ANY || lease->lifetime == 0) { log_dhcp_client(client, "receieved lease lacks address, server " "address or lease lifetime, ignoring"); return -ENOMSG; } if (lease->subnet_mask == INADDR_ANY) { r = dhcp_lease_set_default_subnet_mask(lease); if (r < 0) { log_dhcp_client(client, "receieved lease lacks subnet " "mask, and a fallback one can not be " "generated, ignoring"); return -ENOMSG; } } sd_dhcp_lease_unref(client->lease); client->lease = lease; lease = NULL; log_dhcp_client(client, "OFFER"); return 0; }
static void test_message_init(void) { _cleanup_free_ DHCPMessage *message = NULL; size_t optlen = 4, optoffset; size_t len = sizeof(DHCPMessage) + optlen; uint8_t *magic; message = malloc0(len); assert_se(dhcp_message_init(message, BOOTREQUEST, 0x12345678, DHCP_DISCOVER, optlen, &optoffset) >= 0); assert_se(message->xid == htobe32(0x12345678)); assert_se(message->op == BOOTREQUEST); magic = (uint8_t*)&message->magic; assert_se(magic[0] == 99); assert_se(magic[1] == 130); assert_se(magic[2] == 83); assert_se(magic[3] == 99); assert_se(dhcp_option_parse(message, len, NULL, NULL) >= 0); }