On Tue, May 27, 2014 at 5:41 PM, Zbigniew Jędrzejewski-Szmek <zbys...@in.waw.pl> wrote: > On Mon, May 26, 2014 at 09:39:39PM +0200, Tom Gundersen wrote: >> --- >> src/libsystemd-network/sd-dhcp-server.c | 81 >> ++++++++++++++++++++++++++++++- >> src/libsystemd-network/test-dhcp-server.c | 14 +++--- >> 2 files changed, 86 insertions(+), 9 deletions(-) >> >> diff --git a/src/libsystemd-network/sd-dhcp-server.c >> b/src/libsystemd-network/sd-dhcp-server.c >> index cea7390..be6938b 100644 >> --- a/src/libsystemd-network/sd-dhcp-server.c >> +++ b/src/libsystemd-network/sd-dhcp-server.c >> @@ -27,6 +27,8 @@ >> #include "dhcp-server-internal.h" >> #include "dhcp-internal.h" >> >> +#define DHCP_DEFAULT_LEASE_TIME 60 >> + >> int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr >> *address) { >> assert_return(server, -EINVAL); >> assert_return(address, -EINVAL); >> @@ -277,6 +279,64 @@ int dhcp_server_send_packet(sd_dhcp_server *server, >> sizeof(DHCPPacket) + >> optoffset); >> } >> >> +static int server_message_init(sd_dhcp_server *server, DHCPPacket **ret, >> + uint8_t type, size_t *_optoffset, >> DHCPRequest *req) { >> + _cleanup_free_ DHCPPacket *packet = NULL; >> + size_t optoffset; >> + int r; >> + >> + assert(server); >> + assert(ret); >> + assert(_optoffset); >> + assert(type == DHCP_OFFER); >> + >> + packet = malloc0(sizeof(DHCPPacket) + req->max_optlen); >> + if (!packet) >> + return -ENOMEM; >> + >> + r = dhcp_message_init(&packet->dhcp, BOOTREPLY, >> be32toh(req->message->xid), >> + type, req->max_optlen, &optoffset); >> + if (r < 0) >> + return r; >> + >> + packet->dhcp.flags = req->message->flags; >> + packet->dhcp.giaddr = req->message->giaddr; >> + memcpy(&packet->dhcp.chaddr, &req->message->chaddr, ETH_ALEN); >> + >> + *_optoffset = optoffset; >> + *ret = packet; >> + packet = NULL; >> + >> + return 0; >> +} >> + >> +static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req) { >> + _cleanup_free_ DHCPPacket *packet = NULL; >> + size_t offset; >> + be32_t lease_time; >> + int r; >> + >> + r = server_message_init(server, &packet, DHCP_OFFER, &offset, req); >> + if (r < 0) >> + return r; >> + >> + /* for now offer a random IP */ >> + packet->dhcp.yiaddr = random_u32(); >> + >> + /* for ten seconds */ > The comment appears to be out of date already, it's 60 :)
Ha, indeed. I started out with 10 seconds, but watching wireshark was not possible at that speed :) >> + lease_time = htobe32(DHCP_DEFAULT_LEASE_TIME); >> + r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0, >> + DHCP_OPTION_IP_ADDRESS_LEASE_TIME, 4, >> &lease_time); >> + if (r < 0) >> + return r; >> + >> + r = dhcp_server_send_packet(server, req, packet, DHCP_OFFER, >> offset); >> + if (r < 0) >> + return r; >> + >> + return 0; >> +} >> + >> static int parse_request(uint8_t code, uint8_t len, const uint8_t *option, >> void *user_data) { >> DHCPRequest *req = user_data; >> @@ -377,9 +437,26 @@ int dhcp_server_handle_message(sd_dhcp_server *server, >> DHCPMessage *message, >> /* this only fails on critical errors */ >> return r; >> >> - log_dhcp_server(server, "received message of type %d", type); >> + switch(type) { >> + case DHCP_DISCOVER: >> + log_dhcp_server(server, "DISCOVER (0x%x)", >> + be32toh(req->message->xid)); >> + >> + r = server_send_offer(server, req); >> + if (r < 0) { >> + log_dhcp_server(server, "could not send offer: %s", >> + strerror(-r)); > The error is logged at debug level, but otherwise ignored. Is this enough? It > seems that if > server_send_offer() fails, things are significantly off. Hm, yes, you are right. We should just make sure that server_send_offer can only fail with critical errors and then return r here (same goes for the other server_send_*() methods later in the patches. >> + return 0; >> + } else { >> + log_dhcp_server(server, "OFFER (0x%x)", >> + be32toh(req->message->xid)); >> + return DHCP_OFFER; >> + } >> + >> + break; >> + } >> >> - return 1; >> + return 0; >> } >> >> static int server_receive_message(sd_event_source *s, int fd, >> diff --git a/src/libsystemd-network/test-dhcp-server.c >> b/src/libsystemd-network/test-dhcp-server.c >> index 0cbb4df..ed3aaf9 100644 >> --- a/src/libsystemd-network/test-dhcp-server.c >> +++ b/src/libsystemd-network/test-dhcp-server.c >> @@ -94,13 +94,13 @@ static void test_message_handler(void) { >> assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0); >> assert_se(sd_dhcp_server_start(server) >= 0); >> >> - assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 1); >> + assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == DHCP_OFFER); >> >> test.end = 0; >> /* TODO, shouldn't this fail? */ >> - assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 1); >> + assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == DHCP_OFFER); >> test.end = DHCP_OPTION_END; >> - assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 1); >> + assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == DHCP_OFFER); >> >> test.option_type.code = 0; >> test.option_type.length = 0; >> @@ -109,22 +109,22 @@ static void test_message_handler(void) { >> test.option_type.code = DHCP_OPTION_MESSAGE_TYPE; >> test.option_type.length = 1; >> test.option_type.type = DHCP_DISCOVER; >> - assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 1); >> + assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == DHCP_OFFER); >> >> test.message.op = 0; >> assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 0); >> test.message.op = BOOTREQUEST; >> - assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 1); >> + assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == DHCP_OFFER); >> >> test.message.htype = 0; >> assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 0); >> test.message.htype = ARPHRD_ETHER; >> - assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 1); >> + assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == DHCP_OFFER); >> >> test.message.hlen = 0; >> assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 0); >> test.message.hlen = ETHER_ADDR_LEN; >> - assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == 1); >> + assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, >> sizeof(test)) == DHCP_OFFER); >> } > > Zbyszek _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel