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 :)
> + 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. > + 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