summaryrefslogtreecommitdiffstats
path: root/tinyNET/src/dhcp
diff options
context:
space:
mode:
Diffstat (limited to 'tinyNET/src/dhcp')
-rw-r--r--tinyNET/src/dhcp/tnet_dhcp.c338
-rw-r--r--tinyNET/src/dhcp/tnet_dhcp.h121
-rw-r--r--tinyNET/src/dhcp/tnet_dhcp_message.c355
-rw-r--r--tinyNET/src/dhcp/tnet_dhcp_message.h226
-rw-r--r--tinyNET/src/dhcp/tnet_dhcp_option.c326
-rw-r--r--tinyNET/src/dhcp/tnet_dhcp_option.h291
-rw-r--r--tinyNET/src/dhcp/tnet_dhcp_option_sip.c131
-rw-r--r--tinyNET/src/dhcp/tnet_dhcp_option_sip.h62
8 files changed, 1850 insertions, 0 deletions
diff --git a/tinyNET/src/dhcp/tnet_dhcp.c b/tinyNET/src/dhcp/tnet_dhcp.c
new file mode 100644
index 0000000..8e7dbe6
--- /dev/null
+++ b/tinyNET/src/dhcp/tnet_dhcp.c
@@ -0,0 +1,338 @@
+/*
+* Copyright (C) 2009-2010 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+/**@file tnet_dhcp.c
+ * @brief DHCP/BOOTP (RFC 2131 - Dynamic Host Configuration Protocol) utilities function for P-CSCF discovery(RFC 3319 and 3361).
+ * Also implement: RFC 3315, 3118, 3319, 3825 (Geoconf), 4676 (Civic Addresses Configuration Information) ...
+ *
+ * @author Mamadou Diop <diopmamadou(at)doubango.org>
+ *
+ * @date Created: Sat Nov 8 16:54:58 2009 mdiop
+ */
+#include "tnet_dhcp.h"
+
+#include "../tnet_endianness.h"
+
+#include "tsk_string.h"
+#include "tsk_thread.h"
+#include "tsk_memory.h"
+#include "tsk_time.h"
+#include "tsk_debug.h"
+
+#include <string.h>
+
+// Useful link: http://support.microsoft.com/?scid=kb%3Ben-us%3B169289&x=21&y=14
+// Another one: http://www.iana.org/assignments/bootp-dhcp-parameters/
+// Another one: http://www.slideshare.net/raini/DHCP-Presentation-v102
+// RFC 3319 Dynamic Host Configuration Protocol (DHCPv6) Options for Session Initiation Protocol (SIP) Servers
+// RFC 3361 Dynamic Host Configuration Protocol (DHCP-for-IPv4) Option for Session Initiation Protocol (SIP) Servers
+
+/**@defgroup tnet_dhcp_group DHCPv4/BOOTP (RFC 2131) implementation.
+*/
+
+/**@ingroup tnet_dhcp_group
+* Creates new DHCPv4 context.
+*/
+tnet_dhcp_ctx_t* tnet_dhcp_ctx_create()
+{
+ return tsk_object_new(tnet_dhcp_ctx_def_t);
+}
+
+/**@ingroup tnet_dhcp_group
+* Creates new DHCPv4 parameters.
+*/
+tnet_dhcp_params_t* tnet_dhcp_params_create()
+{
+ return tsk_object_new(tnet_dhcp_params_def_t);
+}
+
+/* FIXME: USE retransmission mech (*2*2...)
+*/
+/**@ingroup tnet_dhcp_group
+*/
+tnet_dhcp_reply_t* tnet_dhcp_send_request(tnet_dhcp_ctx_t* ctx, tnet_dhcp_request_t* request)
+{
+ tsk_buffer_t *output;
+ tnet_dhcp_reply_t* reply = tsk_null;
+ int ret;
+ struct timeval tv;
+ fd_set set;
+ uint64_t timeout = 0;
+ tsk_list_item_t *item;
+ const tnet_interface_t *iface;
+
+ tnet_socket_t *localsocket4 = tsk_null;
+ struct sockaddr_storage server;
+
+ if(!ctx || !request){
+ goto bail;
+ }
+
+ localsocket4 = tnet_socket_create(TNET_SOCKET_HOST_ANY, ctx->port_client, tnet_socket_type_udp_ipv4);
+ if(!TNET_SOCKET_IS_VALID(localsocket4)){
+ TSK_DEBUG_ERROR("Failed to create/bind DHCP client socket.");
+ goto bail;
+ }
+
+ /* Always wait for 200ms before retransmission */
+ tv.tv_sec = 0;
+ tv.tv_usec = (200 * 1000);
+
+ if(tnet_sockaddr_init("255.255.255.255", ctx->server_port, tnet_socket_type_udp_ipv4, &server)){
+ TNET_PRINT_LAST_ERROR("Failed to initialize the DHCP server address");
+ goto bail;
+ }
+
+ /* ENABLE BROADCASTING */
+ {
+#if defined(SOLARIS)
+ char yes = '1';
+#else
+ int yes = 1;
+#endif
+ if(setsockopt(localsocket4->fd, SOL_SOCKET, SO_BROADCAST, (char*)&yes, sizeof(int))){
+ TNET_PRINT_LAST_ERROR("Failed to enable broadcast option");
+ goto bail;
+ }
+ }
+
+ /* Set timeout */
+ timeout = tsk_time_epoch() + ctx->timeout;
+
+ do
+ {
+ /* RFC 2131 - 3.6 Use of DHCP in clients with multiple interfaces
+ A client with multiple network interfaces must use DHCP through each
+ interface independently to obtain configuration information
+ parameters for those separate interfaces.
+ */
+
+ tsk_list_foreach(item, ctx->interfaces){
+ iface = item->data;
+
+ /* Set FD */
+ FD_ZERO(&set);
+ FD_SET(localsocket4->fd, &set);
+
+ /* ciaddr */
+ if(request->type == dhcp_type_inform){
+ struct sockaddr_storage ss;
+ if(!tnet_get_sockaddr(localsocket4->fd, &ss)){
+ uint32_t addr = tnet_htonl_2(&((struct sockaddr_in*)&ss)->sin_addr);
+ memcpy(&request->ciaddr, &addr, 4);
+ }
+ }
+
+ /* chaddr */
+ memset(request->chaddr, 0, sizeof(request->chaddr));
+ request->hlen = iface->mac_address_length > sizeof(request->chaddr) ? sizeof(request->chaddr) : iface->mac_address_length;
+ memcpy(request->chaddr, iface->mac_address, request->hlen);
+
+ /* Serialize and send to the server. */
+ if(!(output = tnet_dhcp_message_serialize(ctx, request))){
+ TSK_DEBUG_ERROR("Failed to serialize the DHCP message.");
+ goto next_iface;
+ }
+ /* Send the request to the DHCP server */
+ if((ret =tnet_sockfd_sendto(localsocket4->fd, (const struct sockaddr*)&server, output->data, output->size))<0){
+ TNET_PRINT_LAST_ERROR("Failed to send DHCP request");
+
+ tsk_thread_sleep(150); // wait 150ms before trying the next iface.
+ goto next_iface;
+ }
+ /* wait for response */
+ if((ret = select(localsocket4->fd+1, &set, NULL, NULL, &tv))<0){ /* Error */
+ TNET_PRINT_LAST_ERROR("select have failed.");
+ tsk_thread_sleep(150); // wait 150ms before trying the next iface.
+ goto next_iface;
+ }
+ else if(ret == 0)
+ { /* timeout ==> do nothing */
+ }
+ else
+ { /* there is data to read */
+ tsk_size_t len = 0;
+ void* data = tsk_null;
+
+ /* Check how how many bytes are pending */
+ if((ret = tnet_ioctlt(localsocket4->fd, FIONREAD, &len))<0){
+ goto next_iface;
+ }
+
+ /* Receive pending data */
+ data = tsk_calloc(len, sizeof(uint8_t));
+ if((ret = tnet_sockfd_recv(localsocket4->fd, data, len, 0))<0){
+ TSK_FREE(data);
+
+ TNET_PRINT_LAST_ERROR("Failed to receive DHCP dgrams.");
+ goto next_iface;
+ }
+
+ /* Parse the incoming response. */
+ reply = tnet_dhcp_message_deserialize(ctx, data, (tsk_size_t)ret);
+ TSK_FREE(data);
+
+ if(reply)
+ { /* response successfuly parsed */
+ if(request->xid != reply->xid)
+ { /* Not same transaction id ==> continue*/
+ TSK_OBJECT_SAFE_FREE(reply);
+ }
+ }
+ }
+
+ next_iface:
+ TSK_OBJECT_SAFE_FREE(output);
+ if(reply){
+ goto bail;
+ }
+ }
+ //break;//FIXME
+ }
+ while(timeout > tsk_time_epoch());
+
+bail:
+ TSK_OBJECT_SAFE_FREE(localsocket4);
+
+ return reply;
+}
+
+/**@ingroup tnet_dhcp_group
+*/
+tnet_dhcp_reply_t* tnet_dhcp_query(tnet_dhcp_ctx_t* ctx, tnet_dhcp_message_type_t type, tnet_dhcp_params_t* params)
+{
+ tnet_dhcp_reply_t* reply = tsk_null;
+ tnet_dhcp_request_t* request = tnet_dhcp_request_create();
+
+ if(!ctx || !params || !request){
+ goto bail;
+ }
+
+ request->type = type;
+ tnet_dhcp_message_add_codes(request, params->codes, params->codes_count);
+
+ reply = tnet_dhcp_send_request(ctx, request);
+
+bail:
+ TSK_OBJECT_SAFE_FREE(request);
+
+ return reply;
+}
+
+/**@ingroup tnet_dhcp_group
+*/
+int tnet_dhcp_params_add_code(tnet_dhcp_params_t* params, tnet_dhcp_option_code_t code)
+{
+ if(params){
+ if(params->codes_count < TNET_DHCP_MAX_CODES){
+ unsigned i;
+ for(i=0; i<params->codes_count; i++){
+ if(params->codes[i] == code){
+ return -3;
+ }
+ }
+ params->codes[params->codes_count++] = code;
+ }
+ else return -2;
+ }
+ return -1;
+}
+
+
+
+//=================================================================================================
+// [[DHCP CONTEXT]] object definition
+//
+static tsk_object_t* tnet_dhcp_ctx_ctor(tsk_object_t * self, va_list * app)
+{
+ tnet_dhcp_ctx_t *ctx = self;
+ if(ctx){
+ tnet_host_t host;
+
+ ctx->vendor_id = tsk_strdup(TNET_DHCP_VENDOR_ID_DEFAULT);
+ if(!tnet_gethostname(&host)){
+ ctx->hostname = tsk_strndup(host, tsk_strlen(host));
+ }
+ ctx->timeout = TNET_DHCP_TIMEOUT_DEFAULT;
+ ctx->max_msg_size = TNET_DHCP_MAX_MSG_SIZE;
+ ctx->port_client = TNET_DHCP_CLIENT_PORT;
+ ctx->server_port = TNET_DHCP_SERVER_PORT;
+ ctx->interfaces = tnet_get_interfaces();
+
+ if(!ctx->interfaces || TSK_LIST_IS_EMPTY(ctx->interfaces)){
+ TSK_DEBUG_ERROR("Failed to retrieve network interfaces.");
+ }
+
+ tsk_safeobj_init(ctx);
+ }
+ return self;
+}
+
+static tsk_object_t* tnet_dhcp_ctx_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_ctx_t *ctx = self;
+ if(ctx){
+ tsk_safeobj_deinit(ctx);
+
+ TSK_FREE(ctx->vendor_id);
+ TSK_FREE(ctx->hostname);
+
+ TSK_OBJECT_SAFE_FREE(ctx->interfaces);
+ }
+ return self;
+}
+
+static const tsk_object_def_t tnet_dhcp_ctx_def_s =
+{
+ sizeof(tnet_dhcp_ctx_t),
+ tnet_dhcp_ctx_ctor,
+ tnet_dhcp_ctx_dtor,
+ tsk_null,
+};
+const tsk_object_def_t *tnet_dhcp_ctx_def_t = &tnet_dhcp_ctx_def_s;
+
+//=================================================================================================
+// [[DHCP PARAMS]] object definition
+//
+static tsk_object_t* tnet_dhcp_params_ctor(tsk_object_t * self, va_list * app)
+{
+ tnet_dhcp_params_t *params = self;
+ if(params){
+ }
+ return self;
+}
+
+static tsk_object_t* tnet_dhcp_params_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_params_t *params = self;
+ if(params){
+ }
+ return self;
+}
+
+static const tsk_object_def_t tnet_dhcp_params_def_s =
+{
+ sizeof(tnet_dhcp_params_t),
+ tnet_dhcp_params_ctor,
+ tnet_dhcp_params_dtor,
+ tsk_null,
+};
+const tsk_object_def_t *tnet_dhcp_params_def_t = &tnet_dhcp_params_def_s;
diff --git a/tinyNET/src/dhcp/tnet_dhcp.h b/tinyNET/src/dhcp/tnet_dhcp.h
new file mode 100644
index 0000000..6b306c5
--- /dev/null
+++ b/tinyNET/src/dhcp/tnet_dhcp.h
@@ -0,0 +1,121 @@
+/*
+* Copyright (C) 2009-2010 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+/**@file tnet_dhcp.h
+ * @brief DHCP (RFC 2131 - Dynamic Host Configuration Protocol) utilities function for P-CSCF discovery(RFC 3319 and 3361)
+ * Also implement: RFC 3315, 3118, 3319, 3825 (Geoconf), 4676 (Civic Addresses Configuration Information)...
+ *
+ * @author Mamadou Diop <diopmamadou(at)doubango.org>
+ *
+ * @date Created: Sat Nov 8 16:54:58 2009 mdiop
+ */
+
+#ifndef TNET_DHCP_H
+#define TNET_DHCP_H
+
+#include "tinynet_config.h"
+
+#include "tnet_dhcp_message.h"
+
+#include "tnet_utils.h"
+
+#include "tsk_object.h"
+#include "tsk_safeobj.h"
+
+TNET_BEGIN_DECLS
+
+/**@ingroup tnet_dhcp_group
+* Default timeout (in milliseconds) value for DHCP requests.
+*/
+#define TNET_DHCP_TIMEOUT_DEFAULT 2000
+
+/**@ingroup tnet_dhcp_group
+* Local port(client) to bind to for incoming DHCP messages as per RFC 2131 subclause 4.1. */
+#define TNET_DHCP_CLIENT_PORT 68
+/**@ingroup tnet_dhcp_group
+* Destination port(Server) for outgoing DHCP messages as per RFC 2131 subclause 4.1. */
+#define TNET_DHCP_SERVER_PORT 67
+
+/**@ingroup tnet_dhcp_group
+* @def TNET_DHCP_VENDOR_ID_DEFAULT
+*/
+/**@ingroup tnet_dhcp_group
+* @def TNET_DHCP_MAX_CODES
+*/
+/**@ingroup tnet_dhcp_group
+* @def TNET_DHCP_MAX_MSG_SIZE
+*/
+#define TNET_DHCP_VENDOR_ID_DEFAULT "doubango/v0.0.0"
+#define TNET_DHCP_MAX_CODES 20
+#define TNET_DHCP_MAX_MSG_SIZE 1500
+
+/**@ingroup tnet_dhcp_group
+* Parameter Request List (55)
+*/
+typedef struct tnet_dhcp_params_s
+{
+ TSK_DECLARE_OBJECT;
+
+ tnet_dhcp_option_code_t codes[TNET_DHCP_MAX_CODES];
+ unsigned codes_count;
+}
+tnet_dhcp_params_t;
+
+/**@ingroup tnet_dhcp_group
+*/
+typedef struct tnet_dhcp_ctx_s
+{
+ TSK_DECLARE_OBJECT;
+
+ char* vendor_id;
+ char* hostname;
+ uint16_t max_msg_size; /**< Option code 57. */
+
+ uint64_t timeout;
+
+ tnet_port_t port_client; /**< Local port to bind to for incloming DHCP messages. Default: 68 */
+ tnet_port_t server_port; /**< Destination port for outgoing DHCP messages. Default: 64 */
+ tnet_interfaces_L_t *interfaces;
+
+ TSK_DECLARE_SAFEOBJ;
+}
+tnet_dhcp_ctx_t;
+
+
+TINYNET_API tnet_dhcp_reply_t* tnet_dhcp_query(tnet_dhcp_ctx_t* ctx, tnet_dhcp_message_type_t type, tnet_dhcp_params_t* params);
+#define tnet_dhcp_query_discover(ctx, params) tnet_dhcp_query(ctx, dhcp_type_discover, params)
+#define tnet_dhcp_query_request(ctx, params) tnet_dhcp_query(ctx, dhcp_type_request, params)
+#define tnet_dhcp_query_decline(ctx, params) tnet_dhcp_query(ctx, dhcp_type_decline, params)
+#define tnet_dhcp_query_release(ctx, params) tnet_dhcp_query(ctx, dhcp_type_release, params)
+#define tnet_dhcp_query_inform(ctx, params) tnet_dhcp_query(ctx, dhcp_type_inform, params)
+
+TINYNET_API int tnet_dhcp_params_add_code(tnet_dhcp_params_t* params, tnet_dhcp_option_code_t code);
+
+
+TINYNET_API tnet_dhcp_ctx_t* tnet_dhcp_ctx_create();
+TINYNET_API tnet_dhcp_params_t* tnet_dhcp_params_create();
+
+TINYNET_GEXTERN const tsk_object_def_t *tnet_dhcp_ctx_def_t;
+TINYNET_GEXTERN const tsk_object_def_t *tnet_dhcp_params_def_t;
+
+TNET_END_DECLS
+
+#endif /* TNET_DHCP_H */
diff --git a/tinyNET/src/dhcp/tnet_dhcp_message.c b/tinyNET/src/dhcp/tnet_dhcp_message.c
new file mode 100644
index 0000000..e4eff3b
--- /dev/null
+++ b/tinyNET/src/dhcp/tnet_dhcp_message.c
@@ -0,0 +1,355 @@
+/*
+* Copyright (C) 2009-2010 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+/**@file tnet_dhcp_message.c
+ * @brief DHCP Message as per RFC 2131 subclause 2.
+ *
+ * @author Mamadou Diop <diopmamadou(at)doubango.org>
+ *
+ * @date Created: Sat Nov 8 16:54:58 2009 mdiop
+ */
+#include "tnet_dhcp_message.h"
+#include "tnet_dhcp.h"
+
+#include "../tnet_utils.h"
+#include "../tnet_endianness.h"
+
+#include "tsk_time.h"
+#include "tsk_memory.h"
+#include "tsk_string.h"
+#include "tsk_debug.h"
+
+#include <string.h>
+
+tnet_dhcp_message_t* tnet_dhcp_message_create(tnet_dhcp_message_op_t opcode)
+{
+ return tsk_object_new(tnet_dhcp_message_def_t, opcode);
+}
+
+tnet_dhcp_request_t* tnet_dhcp_request_create()
+{
+ return tnet_dhcp_message_create(dhcp_op_bootrequest);
+}
+
+tnet_dhcp_message_t* tnet_dhcp_reply_create()
+{
+ return tnet_dhcp_message_create(dhcp_op_bootreply);
+}
+
+tsk_buffer_t* tnet_dhcp_message_serialize(const tnet_dhcp_ctx_t *ctx, const tnet_dhcp_message_t *message)
+{
+ tsk_buffer_t* output = 0;
+ uint8_t _1byte;
+ uint16_t _2bytes;
+ uint32_t _4bytes;
+
+ /* Check message validity */
+ if(!message){
+ goto bail;
+ }
+
+ output = tsk_buffer_create_null();
+
+ /*== OP HTYPE HLEN HOPS */
+ _4bytes = (((uint32_t)(message->op)) << 24) |
+ (((uint32_t)(message->htype)) << 16) |
+ (((uint16_t)(message->hlen)) << 8) | message->hops;
+ _4bytes = tnet_ntohl(_4bytes);
+ tsk_buffer_append(output, &(_4bytes), 4);
+
+ /*== XID */
+ _4bytes = tnet_ntohl(message->xid);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== SECS */
+ _2bytes = tnet_ntohs(message->secs);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /*== FLAGS */
+ _2bytes = tnet_ntohs(message->flags);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /*== CIADDR */
+ _4bytes = tnet_ntohl(message->ciaddr);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== YIADDR */
+ _4bytes = tnet_ntohl(message->yiaddr);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== SIADDR */
+ _4bytes = tnet_ntohl(message->siaddr);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== GIADDR */
+ _4bytes = tnet_ntohl(message->giaddr);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== CHADDR */
+ tsk_buffer_append(output, message->chaddr, sizeof(message->chaddr));
+ /*== sname (unused) */
+ tsk_buffer_append(output, message->sname, sizeof(message->sname));
+ /*== file (unused) */
+ tsk_buffer_append(output, message->file, sizeof(message->file));
+ /*== Magic Cookie */
+ _4bytes = tnet_ntohl(TNET_DHCP_MAGIC_COOKIE);
+ tsk_buffer_append(output, &(_4bytes), 4);
+
+ /*== Message Type (option 53)
+ */
+ tnet_dhcp_option_serializeex(dhcp_code_DHCP_Msg_Type, 1, &message->type, output);
+
+ /*== Client Identifier (option 61) ==> RFC 2132 - 9.14. Client-identifier
+ Code Len Type Client-Identifier
+ +-----+-----+-----+-----+-----+---
+ | 61 | n | t1 | i1 | i2 | ...
+ +-----+-----+-----+-----+-----+---
+ */
+ if(message->hlen){
+ uint8_t client_id[17]; // 16 /*sizeof(chaddr)*/+ 1/*htype*/
+ /*if(client_id)*/{
+ client_id[0] = message->htype;
+ memcpy(&client_id[1], message->chaddr, message->hlen);
+ tnet_dhcp_option_serializeex(dhcp_code_Client_Id, (message->hlen+1), client_id, output);
+ }
+ }
+ /*== Host name(10) ==> RFC 2132 - 3.14. Host Name Option
+ Code Len Host Name
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 12 | n | h1 | h2 | h3 | h4 | h5 | h6 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ if(TNET_DHCP_MESSAGE_IS_REQUEST(message) && ctx->hostname){
+ tnet_dhcp_option_serializeex(dhcp_code_Hostname, tsk_strlen(ctx->hostname), ctx->hostname, output);
+ }
+ /*== Vendor classId(60) ==> RFC 2132 - 9.13. Vendor class identifier
+ Code Len Vendor class Identifier
+ +-----+-----+-----+-----+---
+ | 60 | n | i1 | i2 | ...
+ +-----+-----+-----+-----+---
+ */
+ if(TNET_DHCP_MESSAGE_IS_REQUEST(message) && ctx->vendor_id){
+ tnet_dhcp_option_serializeex(dhcp_code_Class_Id, tsk_strlen(ctx->vendor_id), ctx->vendor_id, output);
+ }
+
+ /*== RFC 2132 - 9.10. Maximum DHCP Message Size (57)
+ Code Len Length
+ +-----+-----+-----+-----+
+ | 57 | 2 | l1 | l2 |
+ +-----+-----+-----+-----+
+ */
+ if(TNET_DHCP_MESSAGE_IS_REQUEST(message) && ctx->max_msg_size){
+ _2bytes = tnet_ntohs(ctx->max_msg_size);
+ tnet_dhcp_option_serializeex(dhcp_code_DHCP_Max_Msg_Size, 2, &_2bytes, output);
+ }
+
+ /*== DHCP Options
+ */
+ {
+ tsk_list_item_t *item;
+ tnet_dhcp_option_t* option;
+ tsk_list_foreach(item, message->options)
+ {
+ option = (tnet_dhcp_option_t*)item->data;
+ if(tnet_dhcp_option_serialize(option, output)){
+ TSK_DEBUG_WARN("Failed to serialize DHCP OPTION (%u)", option->code);
+ }
+ }
+ }
+
+ /* RFC 2131 - 4.1 Constructing and sending DHCP messages
+ The last option must always be the 'end' option.
+ */
+ _1byte = dhcp_code_End;
+ tsk_buffer_append(output, &(_1byte), 1);
+
+bail:
+ return output;
+}
+
+tnet_dhcp_message_t* tnet_dhcp_message_deserialize(const struct tnet_dhcp_ctx_s *ctx, const uint8_t *data, tsk_size_t size)
+{
+ tnet_dhcp_message_t *message = 0;
+ uint8_t *dataPtr, *dataEnd, *dataStart;
+
+ if(!data || !size)
+ {
+ goto bail;
+ }
+
+ if(size < TNET_DHCP_MESSAGE_MIN_SIZE){
+ TSK_DEBUG_ERROR("DHCP message too short.");
+ goto bail;
+ }
+
+ if(!(message = tnet_dhcp_reply_create())){ /* If REQUEST OP will be overridedden */
+ TSK_DEBUG_ERROR("Failed to create new DHCP message.");
+ goto bail;
+ }
+
+ dataPtr = (uint8_t*)data;
+ dataStart = dataPtr;
+ dataEnd = (dataStart + size);
+
+ /*== op (1)*/
+ message->op = *(dataPtr++);
+ /*== htype (1) */
+ message->htype = *(dataPtr++);
+ /*== hlen (1) */
+ message->hlen = *(dataPtr++);
+ /*== htype (1) */
+ message->hops = *(dataPtr++);
+ /*== xid (4) */
+ message->xid= tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== secs (2) */
+ message->secs = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+ /*== flags (2) */
+ message->flags = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+ /*== ciaddr (4) */
+ message->ciaddr= tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== yiaddr (4) */
+ message->yiaddr= tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== siaddr (4) */
+ message->siaddr= tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== giaddr (4) */
+ message->giaddr= tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== chaddr (16[max]) */
+ memcpy(message->chaddr, dataPtr, message->hlen>16 ? 16 : message->hlen);
+ dataPtr += 16;
+ /*== sname (64) */
+ memcpy(message->sname, dataPtr, 64);
+ dataPtr += 64;
+ /*== file (128) */
+ memcpy(message->file, dataPtr, 128);
+ dataPtr += 128;
+ /*== Magic Cookie (4) */
+ if(tnet_htonl_2(dataPtr) != TNET_DHCP_MAGIC_COOKIE){
+ TSK_DEBUG_ERROR("Invalid DHCP magic cookie.");
+ // Do not exit ==> continue parsing.
+ }
+ dataPtr += 4;
+
+ /*== options (variable) */
+ while(dataPtr<dataEnd && *dataPtr!=dhcp_code_End)
+ {
+ tnet_dhcp_option_t* option = tnet_dhcp_option_deserialize(dataPtr, (dataEnd-dataPtr));
+ if(option && option->value){
+
+ if(option->code == dhcp_code_DHCP_Msg_Type){
+ message->type = (tnet_dhcp_message_type_t)*TSK_BUFFER_TO_U8(option->value);
+ }
+
+ dataPtr += option->value->size + 2/*Code Len*/;
+ tsk_list_push_back_data(message->options, (void**)&option);
+ }
+ else break;
+ }
+
+bail:
+ return message;
+}
+
+
+const tnet_dhcp_option_t* tnet_dhcp_message_find_option(const tnet_dhcp_message_t *message, tnet_dhcp_option_code_t code)
+{
+ tsk_list_item_t *item;
+
+ if(!message){
+ goto bail;
+ }
+
+ tsk_list_foreach(item, message->options)
+ {
+ if(((tnet_dhcp_option_t*)item->data)->code == code){
+ return ((tnet_dhcp_option_t*)item->data);
+ }
+ }
+
+bail:
+ return 0;
+}
+
+int tnet_dhcp_message_add_codes(tnet_dhcp_message_t *self, tnet_dhcp_option_code_t codes[], unsigned codes_count)
+{
+ int ret = -1;
+
+ if(!self){
+ goto bail;
+ }
+ if(codes_count){
+ unsigned i;
+
+ tnet_dhcp_option_paramslist_t* option = (tnet_dhcp_option_paramslist_t*)tnet_dhcp_message_find_option(self, dhcp_code_Parameter_List);
+ if(!option){
+ tnet_dhcp_option_paramslist_t *option_paramslist = tnet_dhcp_option_paramslist_create();
+ option = option_paramslist;
+ tsk_list_push_back_data(self->options, (void**)&option_paramslist);
+ }
+
+ for(i=0; i<codes_count; i++){
+ if((ret = tnet_dhcp_option_paramslist_add_code(option, codes[i]))){
+ break;
+ }
+ }
+ }
+
+bail:
+ return ret;
+}
+
+
+//=================================================================================================
+// [[DHCP MESSAGE]] object definition
+//
+static tsk_object_t* tnet_dhcp_message_ctor(tsk_object_t * self, va_list * app)
+{
+ tnet_dhcp_message_t *message = self;
+ if(message){
+ static uint32_t __dhcpmessage_unique_xid = 0;//(uint32_t)tsk_time_epoch();
+
+ message->op = va_arg(*app, tnet_dhcp_message_op_t);
+ message->htype = tnet_htype_Ethernet_10Mb;
+ message->hlen = 0x06;
+
+ message->xid = ++(__dhcpmessage_unique_xid);
+ message->options = tsk_list_create();
+ }
+ return self;
+}
+
+static tsk_object_t* tnet_dhcp_message_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_message_t *message = self;
+ if(message){
+ TSK_OBJECT_SAFE_FREE(message->options);
+ }
+ return self;
+}
+
+static const tsk_object_def_t tnet_dhcp_message_def_s =
+{
+ sizeof(tnet_dhcp_message_t),
+ tnet_dhcp_message_ctor,
+ tnet_dhcp_message_dtor,
+ tsk_null,
+};
+const tsk_object_def_t *tnet_dhcp_message_def_t = &tnet_dhcp_message_def_s;
+
diff --git a/tinyNET/src/dhcp/tnet_dhcp_message.h b/tinyNET/src/dhcp/tnet_dhcp_message.h
new file mode 100644
index 0000000..4101e9b
--- /dev/null
+++ b/tinyNET/src/dhcp/tnet_dhcp_message.h
@@ -0,0 +1,226 @@
+/*
+* Copyright (C) 2009-2010 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+/**@file tnet_dhcp_message.h
+ * @brief DHCP Message as per RFC 2131 subclause 2.
+ *
+ * @author Mamadou Diop <diopmamadou(at)doubango.org>
+ *
+ * @date Created: Sat Nov 8 16:54:58 2009 mdiop
+ */
+
+#ifndef TNET_DHCP_MESSAGE_H
+#define TNET_DHCP_MESSAGE_H
+
+#include "tinynet_config.h"
+
+#include "tnet_dhcp_option.h"
+#include "tnet_hardwares.h"
+
+#include "tsk_buffer.h"
+
+TNET_BEGIN_DECLS
+
+struct tnet_dhcp_ctx_s;
+
+#define TNET_DHCP_MESSAGE_IS_REQUEST(self) ((self) && ((self)->op==dhcp_op_bootrequest))
+#define TNET_DHCP_MESSAGE_IS_REPLY(self) ((self) && ((self)->op==dhcp_op_bootreply))
+
+#define TNET_DHCP_MAGIC_COOKIE 0x63825363 /**< DHCP magic cookie (99, 130, 83 and 99 in decimal).*/
+
+#define TNET_DHCP_MESSAGE_MIN_SIZE 223 /* Is it rigth? */
+
+/** List of all supported DHCP message (see RFC 2131).
+*/
+typedef enum tnet_dhcp_message_type_e
+{
+ /**< DHCPDISCOVER - Client broadcast to locate available servers.
+ */
+ dhcp_type_discover = 1,
+
+ /**< DHCPOFFER - Server to client in response to DHCPDISCOVER with
+ offer of configuration parameters.
+ */
+ dhcp_type_offer = 2,
+
+ /**< DHCPREQUEST - Client message to servers either (a) requesting
+ offered parameters from one server and implicitly
+ declining offers from all others, (b) confirming
+ correctness of previously allocated address after,
+ e.g., system reboot, or (c) extending the lease on a
+ particular network address.
+ */
+ dhcp_type_request = 3,
+
+ /**< DHCPDECLINE - Client to server indicating network address is already
+ in use.
+ */
+ dhcp_type_decline = 4,
+
+ /**< DHCPACK - Server to client with configuration parameters,
+ including committed network address.
+ */
+ dhcp_type_ack = 5,
+
+ /**< DHCPNAK - Server to client indicating client's notion of network
+ address is incorrect (e.g., client has moved to new
+ subnet) or client's lease as expired
+ */
+ dhcp_type_nack = 6,
+
+ /**< DHCPRELEASE - Client to server relinquishing network address and
+ cancelling remaining lease.
+ */
+ dhcp_type_release = 7,
+
+ /**< DHCPINFORM - Client to server, asking only for local configuration
+ parameters; client already has externally configured
+ network address.
+ */
+ dhcp_type_inform = 8,
+}
+tnet_dhcp_message_type_t;
+
+/** DHCP message OP code / message type.
+*/
+typedef enum tnet_dhcp_message_op_e
+{
+ dhcp_op_bootrequest = 1,
+ dhcp_op_bootreply = 2
+}
+tnet_dhcp_message_op_t;
+
+/** BOOTP/DHCP message as per RFC 2131 subclause 2.
+*/
+typedef struct tnet_dhcp_message_s
+{
+ TSK_DECLARE_OBJECT;
+
+ /**< DHCP message type. Mandatory.
+ */
+ tnet_dhcp_message_type_t type;
+ /*
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | op (1) | htype (1) | hlen (1) | hops (1) |
+ +---------------+---------------+---------------+---------------+
+ | xid (4) |
+ +-------------------------------+-------------------------------+
+ | secs (2) | flags (2) |
+ +-------------------------------+-------------------------------+
+ | ciaddr (4) |
+ +---------------------------------------------------------------+
+ | yiaddr (4) |
+ +---------------------------------------------------------------+
+ | siaddr (4) |
+ +---------------------------------------------------------------+
+ | giaddr (4) |
+ +---------------------------------------------------------------+
+ | |
+ | chaddr (16) |
+ | |
+ | |
+ +---------------------------------------------------------------+
+ | |
+ | sname (64) |
+ +---------------------------------------------------------------+
+ | |
+ | file (128) |
+ +---------------------------------------------------------------+
+ | |
+ | options (variable) |
+ +---------------------------------------------------------------+
+ */
+
+ /**< Message op code / message type (1-byte).
+ 1 = BOOTREQUEST, 2 = BOOTREPLY
+ */
+ tnet_dhcp_message_op_t op;
+ /**< Hardware address type, see ARP section in "Assigned Numbers" RFC; e.g., '1' = 10mb ethernet.
+ For more information see RFC 1340.
+ */
+ tnet_hardware_type_t htype;
+ /**< Hardware address length (e.g. '6' for 10mb ethernet). tsk_strlen(chaddr).
+ */
+ uint8_t hlen;
+ /**< Client sets to zero, optionally used by relay agents when booting via a relay agent.
+ */
+ uint8_t hops;
+ /**< Transaction ID, a random number chosen by the client, used by the client
+ and server to associate messages and responses between a client and a server.
+ */
+ uint32_t xid;
+ /**< Filled in by client, seconds elapsed since client began address acquisition or renewal process.
+ */
+ uint16_t secs;
+ /**< Flags (see figure 2)
+ */
+ uint16_t flags;
+ /**< Client IP address; only filled in if client is in BOUND, RENEW or REBINDING
+ state and can respond to ARP requests.
+ */
+ uint32_t ciaddr;
+ /**< 'your' (client) IP address.
+ */
+ uint32_t yiaddr;
+ /**< IP address of next server to use in bootstrap;
+ returned in DHCPOFFER, DHCPACK by server.
+ */
+ uint32_t siaddr;
+ /**< Relay agent IP address, used in booting via a relay agent.
+ */
+ uint32_t giaddr;
+ /**< Client hardware address.
+ */
+ uint8_t chaddr[16];
+ /**< Optional server host name, null terminated string.
+ */
+ uint8_t sname[64];
+ /**<Boot file name, null terminated string; "generic" name or null in DHCPDISCOVER,
+ fully qualifieddirectory-path name in DHCPOFFER.
+ */
+ uint8_t file[128];
+ /**Optional parameters field. See the options documents for a list of defined options.
+ For more information please refer to RFC 2132, 1497 and 1533.
+ */
+ tnet_dhcp_options_L_t *options;
+}
+tnet_dhcp_message_t;
+
+typedef tsk_list_t tnet_dhcp_messages_L_t;
+typedef tnet_dhcp_message_t tnet_dhcp_request_t; /**< BOOTREQUEST message. */
+typedef tnet_dhcp_message_t tnet_dhcp_reply_t; /**< BOOTREPLY message. */
+
+tsk_buffer_t* tnet_dhcp_message_serialize(const struct tnet_dhcp_ctx_s *ctx, const tnet_dhcp_message_t *self);
+tnet_dhcp_message_t* tnet_dhcp_message_deserialize(const struct tnet_dhcp_ctx_s *ctx, const uint8_t *data, tsk_size_t size);
+const tnet_dhcp_option_t* tnet_dhcp_message_find_option(const tnet_dhcp_message_t *self, tnet_dhcp_option_code_t code);
+int tnet_dhcp_message_add_codes(tnet_dhcp_message_t *self, tnet_dhcp_option_code_t codes[], unsigned codes_count);
+
+TINYNET_API tnet_dhcp_message_t* tnet_dhcp_message_create(tnet_dhcp_message_op_t opcode);
+TINYNET_API tnet_dhcp_request_t* tnet_dhcp_request_create();
+TINYNET_API tnet_dhcp_message_t* tnet_dhcp_reply_create();
+
+TINYNET_GEXTERN const tsk_object_def_t *tnet_dhcp_message_def_t;
+
+TNET_END_DECLS
+
+#endif /* TNET_DHCP_MESSAGE_H */
diff --git a/tinyNET/src/dhcp/tnet_dhcp_option.c b/tinyNET/src/dhcp/tnet_dhcp_option.c
new file mode 100644
index 0000000..39a28e9
--- /dev/null
+++ b/tinyNET/src/dhcp/tnet_dhcp_option.c
@@ -0,0 +1,326 @@
+/*
+* Copyright (C) 2009-2010 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+/**@file tnet_dhcp_option.c
+ * @brief DHCP Options and BOOTP Vendor Extensions as per RFC 2132.
+ *
+ * @author Mamadou Diop <diopmamadou(at)doubango.org>
+ *
+ * @date Created: Sat Nov 8 16:54:58 2009 mdiop
+ */
+#include "tnet_dhcp_option.h"
+
+#include "tnet_dhcp_option_sip.h"
+
+#include "../tnet_types.h"
+#include "../tnet_endianness.h"
+
+#include "tsk_memory.h"
+#include "tsk_debug.h"
+
+tnet_dhcp_option_t* tnet_dhcp_option_create(tnet_dhcp_option_code_t code)
+{
+ return tsk_object_new(tnet_dhcp_option_def_t, code);
+}
+
+tnet_dhcp_option_paramslist_t* tnet_dhcp_option_paramslist_create()
+{
+ return tsk_object_new(tnet_dhcp_option_paramslist_def_t);
+}
+
+tnet_dhcp_option_dns_t* tnet_dhcp_option_dns_create(const void* payload, tsk_size_t payload_size)
+{
+ return tsk_object_new(tnet_dhcp_option_dns_def_t, payload, payload_size);
+}
+
+/** Initializes DHCPv4 option.
+ *
+ * @param [in,out] self The option to initialize.
+ * @param code The code of the option to initialize.
+ *
+ * @return Zero if succeed and non-zero error code otherwise.
+**/
+int tnet_dhcp_option_init(tnet_dhcp_option_t *self, tnet_dhcp_option_code_t code)
+{
+ if(self)
+ {
+ if(!self->initialized)
+ {
+ self->code = code;
+ //option->value = tsk_buffer_create_null();
+
+ self->initialized = tsk_true;
+ return 0;
+ }
+ return -2;
+ }
+ return -1;
+}
+
+int tnet_dhcp_option_deinit(tnet_dhcp_option_t *self)
+{
+ if(self)
+ {
+ if(self->initialized)
+ {
+ TSK_OBJECT_SAFE_FREE(self->value);
+
+ self->initialized = tsk_false;
+ return 0;
+ }
+ return -2;
+ }
+ return -1;
+}
+
+tnet_dhcp_option_t* tnet_dhcp_option_deserialize(const void* data, tsk_size_t size)
+{
+ tnet_dhcp_option_t *option = 0;
+ uint8_t* dataPtr = ((uint8_t*)data);
+ //uint8_t* dataEnd = (dataPtr+size);
+
+ tnet_dhcp_option_code_t code;
+ uint8_t len;
+
+ /* Check validity */
+ if(!dataPtr || size<2/*Code Len*/){
+ goto bail;
+ }
+
+ code = (tnet_dhcp_option_code_t)*dataPtr++;
+ len = *dataPtr++;
+
+ switch(code)
+ {
+ case dhcp_code_SIP_Servers_DHCP_Option:
+ {
+ option = (tnet_dhcp_option_t *)tnet_dhcp_option_sip_create(dataPtr, len);
+ break;
+ }
+
+ case dhcp_code_Domain_Server:
+ {
+ option = (tnet_dhcp_option_t *)tnet_dhcp_option_dns_create(dataPtr, len);
+ break;
+ }
+
+ default:
+ {
+ option = tnet_dhcp_option_create(code);
+ }
+ }
+
+ /* In all case */
+ if(option && !option->value && len){
+ option->value = tsk_buffer_create((((uint8_t*)data) + 2/*Code Len*/), len);
+ }
+
+bail:
+ return option;
+}
+
+int tnet_dhcp_option_serialize(const tnet_dhcp_option_t* self, tsk_buffer_t *output)
+{
+ if(!self || !output){
+ return -1;
+ }
+
+ /* Code */
+ tsk_buffer_append(output, &(self->code), 1);
+
+ if(self->value){
+ /* Length */
+ tsk_buffer_append(output, &(self->value->size), 1);
+
+ /* Value */
+ tsk_buffer_append(output, self->value->data, self->value->size);
+ }
+ else{
+ /* Length */
+ static uint8_t zero = 0x00;
+ tsk_buffer_append(output, &zero, 1);
+ }
+
+ return 0;
+}
+
+int tnet_dhcp_option_serializeex(tnet_dhcp_option_code_t code, uint8_t length, const void* value, tsk_buffer_t *output)
+{
+ if(value && length && output){
+ tsk_buffer_append(output, &(code), 1);
+ tsk_buffer_append(output, &(length), 1);
+ tsk_buffer_append(output, value, length);
+
+ return 0;
+ }
+ return -1;
+}
+
+//
+// [[DHCP OPTION]] object definition
+//
+static tsk_object_t* tnet_dhcp_option_ctor(tsk_object_t * self, va_list * app)
+{
+ tnet_dhcp_option_t *option = self;
+ if(option){
+ tnet_dhcp_option_init(option, va_arg(*app, tnet_dhcp_option_code_t));
+ }
+ return self;
+}
+
+static tsk_object_t* tnet_dhcp_option_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_option_t *option = self;
+ if(option){
+ tnet_dhcp_option_deinit(option);
+ }
+ return self;
+}
+
+static const tsk_object_def_t tnet_dhcp_option_def_s =
+{
+ sizeof(tnet_dhcp_option_t),
+ tnet_dhcp_option_ctor,
+ tnet_dhcp_option_dtor,
+ tsk_null,
+};
+const tsk_object_def_t *tnet_dhcp_option_def_t = &tnet_dhcp_option_def_s;
+
+
+
+/*=======================================================================================
+* RFC 2132 - 9.8. Parameter Request List
+*=======================================================================================*/
+int tnet_dhcp_option_paramslist_add_code(tnet_dhcp_option_paramslist_t* self, tnet_dhcp_option_code_t code)
+{
+ if(self){
+ if(!TNET_DHCP_OPTION(self)->value){
+ TNET_DHCP_OPTION(self)->value = tsk_buffer_create_null();
+ }
+ return tsk_buffer_append(TNET_DHCP_OPTION(self)->value, &code, 1);
+ }
+ return -1;
+}
+
+//
+// [[DHCP OPTION - RFC 2132 9.8. Parameter Request List]] object definition
+//
+static tsk_object_t* tnet_dhcp_option_paramslist_ctor(tsk_object_t * self, va_list * app)
+{
+ tnet_dhcp_option_paramslist_t *option = self;
+ if(option){
+ /* init base */
+ tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_Parameter_List);
+ }
+ return self;
+}
+
+static tsk_object_t* tnet_dhcp_option_paramslist_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_option_paramslist_t *option = self;
+ if(option){
+ /* deinit base */
+ tnet_dhcp_option_deinit(TNET_DHCP_OPTION(option));
+ }
+ return self;
+}
+
+static const tsk_object_def_t tnet_dhcp_option_paramslist_def_s =
+{
+ sizeof(tnet_dhcp_option_paramslist_t),
+ tnet_dhcp_option_paramslist_ctor,
+ tnet_dhcp_option_paramslist_dtor,
+ tsk_null,
+};
+const tsk_object_def_t *tnet_dhcp_option_paramslist_def_t = &tnet_dhcp_option_paramslist_def_s;
+
+
+/*=======================================================================================
+* RFC 2132 - 3.8. Domain Name Server Option
+*=======================================================================================*/
+//
+// [[DHCP OPTION - RFC 2132 3.8. Domain Name Server Option]] object definition
+//
+static tsk_object_t* tnet_dhcp_option_dns_ctor(tsk_object_t * self, va_list * app)
+{
+ tnet_dhcp_option_dns_t *option = self;
+ if(option){
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ const uint8_t* payloadPtr = (const uint8_t*)payload;
+ const uint8_t* payloadEnd = (payloadPtr + payload_size);
+
+ /* init base */
+ tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_Domain_Server);
+
+ option->servers = tsk_list_create();
+
+ if(payload_size<4 || payload_size%4){
+ TSK_DEBUG_ERROR("DHCP - The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.");
+ }
+ else{
+ tsk_size_t i;
+ char* ip4 = 0;
+ uint32_t address;
+ tsk_string_t* addrstring;
+
+ for(i=0; i<payload_size && (payloadPtr< payloadEnd); i+=4){
+ /*
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ address = tnet_htonl_2(payloadPtr);
+ tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
+
+ addrstring = tsk_string_create(ip4);
+ tsk_list_push_back_data(option->servers, (void*)&addrstring);
+
+ TSK_FREE(ip4);
+ payloadPtr+= 4;
+ }
+ }
+ }
+ return self;
+}
+
+static tsk_object_t* tnet_dhcp_option_dns_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_option_dns_t *option = self;
+ if(option){
+ /* deinit base */
+ tnet_dhcp_option_deinit(TNET_DHCP_OPTION(option));
+
+ TSK_OBJECT_SAFE_FREE(option->servers);
+ }
+ return self;
+}
+
+static const tsk_object_def_t tnet_dhcp_option_dns_def_s =
+{
+ sizeof(tnet_dhcp_option_dns_t),
+ tnet_dhcp_option_dns_ctor,
+ tnet_dhcp_option_dns_dtor,
+ tsk_null,
+};
+const tsk_object_def_t *tnet_dhcp_option_dns_def_t = &tnet_dhcp_option_dns_def_s;
diff --git a/tinyNET/src/dhcp/tnet_dhcp_option.h b/tinyNET/src/dhcp/tnet_dhcp_option.h
new file mode 100644
index 0000000..b9c313e
--- /dev/null
+++ b/tinyNET/src/dhcp/tnet_dhcp_option.h
@@ -0,0 +1,291 @@
+/*
+* Copyright (C) 2009-2010 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+/**@file tnet_dhcp_option.h
+ * @brief DHCP Options and BOOTP Vendor Extensions as per RFC 2132.
+ *
+ * @author Mamadou Diop <diopmamadou(at)doubango.org>
+ *
+ * @date Created: Sat Nov 8 16:54:58 2009 mdiop
+ */
+
+#ifndef TNET_DHCP_OPTION_H
+#define TNET_DHCP_OPTION_H
+
+#include "tinynet_config.h"
+
+#include "tsk_buffer.h"
+#include "tsk_string.h"
+
+TNET_BEGIN_DECLS
+
+#define TNET_DHCP_OPTION(self) ((tnet_dhcp_option_t*)(self))
+
+typedef enum tnet_dhcp_option_code_e
+{
+ dhcp_code_Pad= 0 ,/**< Pad 0 None [RFC2132] */
+ dhcp_code_Subnet_Mask= 1 ,/**< Subnet Mask 4 Subnet Mask Value [RFC2132] */
+ dhcp_code_Time_Offset= 2 ,/**< Time Offset 4 Time Offset in Seconds from UTC [RFC2132] (note: deprecated by 100 and 101) */
+ dhcp_code_Router= 3 ,/**< Router N N/4 Router addresses [RFC2132] */
+ dhcp_code_Time_Server= 4 ,/**< Time Server N N/4 Timeserver addresses [RFC2132] */
+ dhcp_code_Name_Server= 5 ,/**< Name Server N N/4 IEN-116 Server addresses [RFC2132] */
+ dhcp_code_Domain_Server= 6 ,/**< Domain Server N N/4 DNS Server addresses [RFC2132] */
+ dhcp_code_Log_Server= 7 ,/**< Log Server N N/4 Logging Server addresses [RFC2132] */
+ dhcp_code_Quotes_Server= 8 ,/**< Quotes Server N N/4 Quotes Server addresses [RFC2132] */
+ dhcp_code_LPR_Server= 9 ,/**< LPR Server N N/4 Printer Server addresses [RFC2132] */
+ dhcp_code_Impress_Server= 10 ,/**< Impress Server N N/4 Impress Server addresses [RFC2132] */
+ dhcp_code_RLP_Server= 11 ,/**< RLP Server N N/4 RLP Server addresses [RFC2132] */
+ dhcp_code_Hostname= 12 ,/**< Hostname N Hostname string [RFC2132] */
+ dhcp_code_Boot_File_Size= 13 ,/**< Boot File Size 2 Size of boot file in 512 byte chunks [RFC2132] */
+ dhcp_code_Merit_Dump_File= 14 ,/**< Merit Dump File N Client to dump and name the file to dump it to [RFC2132] */
+ dhcp_code_Domain_Name= 15 ,/**< Domain Name N The DNS domain name of the client [RFC2132] */
+ dhcp_code_Swap_Server= 16 ,/**< Swap Server N Swap Server address [RFC2132] */
+ dhcp_code_Root_Path= 17 ,/**< Root Path N Path name for root disk [RFC2132] */
+ dhcp_code_Extension_File= 18 ,/**< Extension File N Path name for more BOOTP info [RFC2132] */
+ dhcp_code_Forward_On_Off= 19 ,/**< Forward On/Off 1 Enable/Disable IP Forwarding [RFC2132] */
+ dhcp_code_SrcRte_On_Off = 20 ,/**< SrcRte On/Off 1 Enable/Disable Source Routing [RFC2132] */
+ dhcp_code_Policy_Filter= 21 ,/**< Policy Filter N Routing Policy Filters [RFC2132] */
+ dhcp_code_Max_DG_Assembly= 22 ,/**< Max DG Assembly 2 Max Datagram Reassembly Size [RFC2132] */
+ dhcp_code_Default_IP_TTL= 23 ,/**< Default IP TTL 1 Default IP Time to Live [RFC2132] */
+ dhcp_code_MTU_Timeout= 24 ,/**< MTU Timeout 4 Path MTU Aging Timeout [RFC2132] */
+ dhcp_code_MTU_Plateau= 25 ,/**< MTU Plateau N Path MTU Plateau Table [RFC2132] */
+ dhcp_code_MTU_Interface= 26 ,/**< MTU Interface 2 Interface MTU Size [RFC2132] */
+ dhcp_code_MTU_Subnet= 27 ,/**< MTU Subnet 1 All Subnets are Local [RFC2132] */
+ dhcp_code_Broadcast_Address= 28 ,/**< Broadcast Address 4 Broadcast Address [RFC2132] */
+ dhcp_code_Mask_Discovery= 29 ,/**< Mask Discovery 1 Perform Mask Discovery [RFC2132] */
+ dhcp_code_Mask_Supplier= 30 ,/**< Mask Supplier 1 Provide Mask to Others [RFC2132] */
+ dhcp_code_Router_Discovery= 31 ,/**< Router Discovery 1 Perform Router Discovery [RFC2132] */
+ dhcp_code_Router_Request= 32 ,/**< Router Request 4 Router Solicitation Address [RFC2132] */
+ dhcp_code_Static_Route= 33 ,/**< Static Route N Static Routing Table [RFC2132] */
+ dhcp_code_Trailers= 34 ,/**< Trailers 1 Trailer Encapsulation [RFC2132] */
+ dhcp_code_ARP_Timeout= 35 ,/**< ARP Timeout 4 ARP Cache Timeout [RFC2132] */
+ dhcp_code_Ethernet= 36 ,/**< Ethernet 1 Ethernet Encapsulation [RFC2132] */
+ dhcp_code_Default_TCP_TTL= 37 ,/**< Default TCP TTL 1 Default TCP Time to Live [RFC2132] */
+ dhcp_code_Keepalive_Time= 38 ,/**< Keepalive Time 4 TCP Keepalive Interval [RFC2132] */
+ dhcp_code_Keepalive_Data= 39 ,/**< Keepalive Data 1 TCP Keepalive Garbage [RFC2132] */
+ dhcp_code_NIS_Domain= 40 ,/**< NIS Domain N NIS Domain Name [RFC2132] */
+ dhcp_code_NIS_Servers= 41 ,/**< NIS Servers N NIS Server Addresses [RFC2132] */
+ dhcp_code_NTP_Servers= 42 ,/**< NTP Servers N NTP Server Addresses [RFC2132] */
+ dhcp_code_Vendor_Specific= 43 ,/**< Vendor Specific N Vendor Specific Information [RFC2132] */
+ dhcp_code_NETBIOS_Name_Srv= 44 ,/**< NETBIOS Name Srv N NETBIOS Name Servers [RFC2132] */
+ dhcp_code_NETBIOS_Dist_Srv= 45 ,/**< NETBIOS Dist Srv N NETBIOS Datagram Distribution [RFC2132] */
+ dhcp_code_NETBIOS_Node_Type= 46 ,/**< NETBIOS Node Type 1 NETBIOS Node Type [RFC2132] */
+ dhcp_code_NETBIOS_Scope= 47 ,/**< NETBIOS Scope N NETBIOS Scope [RFC2132] */
+ dhcp_code_X_Window_Font= 48 ,/**< X Window Font N X Window Font Server [RFC2132] */
+ dhcp_code_X_Window_Manager= 49 ,/**< X Window Manager N X Window Display Manager [RFC2132] */
+ dhcp_code_Address_Request= 50 ,/**< Address Request 4 Requested IP Address [RFC2132] */
+ dhcp_code_Address_Time= 51 ,/**< Address Time 4 IP Address Lease Time [RFC2132] */
+ dhcp_code_Overload= 52 ,/**< Overload 1 Overload "sname" or "file" [RFC2132] */
+ dhcp_code_DHCP_Msg_Type= 53 ,/**< DHCP Msg Type 1 DHCP Message Type [RFC2132] */
+ dhcp_code_DHCP_Server_Id= 54 ,/**< DHCP Server Id 4 DHCP Server Identification [RFC2132] */
+ dhcp_code_Parameter_List= 55 ,/**< Parameter List N Parameter Request List [RFC2132] */
+ dhcp_code_DHCP_Error_Message= 56 ,/**< DHCP Message N DHCP Error Message [RFC2132] */
+ dhcp_code_DHCP_Max_Msg_Size= 57 ,/**< DHCP Max Msg Size 2 DHCP Maximum Message Size [RFC2132] */
+ dhcp_code_Renewal_Time= 58 ,/**< Renewal Time 4 DHCP Renewal (T1) Time [RFC2132] */
+ dhcp_code_Rebinding_Time= 59 ,/**< Rebinding Time 4 DHCP Rebinding (T2) Time [RFC2132] */
+ dhcp_code_Class_Id= 60 ,/**< Class Id N Class Identifier [RFC2132] */
+ dhcp_code_Client_Id= 61 ,/**< Client Id N Client Identifier [RFC2132] */
+ dhcp_code_NetWare_IP_Domain= 62 ,/**< NetWare/IP Domain N NetWare/IP Domain Name [RFC2242] */
+ dhcp_code_NetWare_IP_Option= 63 ,/**< NetWare/IP Option N NetWare/IP sub Options [RFC2242] */
+ dhcp_code_NIS_Domain_Name= 64 ,/**< NIS-Domain-Name N NIS+ v3 Client Domain Name [RFC2132] */
+ dhcp_code_NIS_Server_Addr = 65 ,/**< NIS-Server-Addr N NIS+ v3 Server Addresses [RFC2132] */
+ dhcp_code_Server_Name= 66 ,/**< Server-Name N TFTP Server Name [RFC2132] */
+ dhcp_code_Bootfile_Name= 67 ,/**< Bootfile-Name N Boot File Name [RFC2132] */
+ dhcp_code_Home_Agent_Addrs= 68 ,/**< Home-Agent-Addrs N Home Agent Addresses [RFC2132] */
+ dhcp_code_SMTP_Server= 69 ,/**< SMTP-Server N Simple Mail Server Addresses [RFC2132] */
+ dhcp_code_POP3_Server= 70 ,/**< POP3-Server N Post Office Server Addresses [RFC2132] */
+ dhcp_code_NNTP_Server= 71 ,/**< NNTP-Server N Network News Server Addresses [RFC2132] */
+ dhcp_code_WWW_Server= 72 ,/**< WWW-Server N WWW Server Addresses [RFC2132] */
+ dhcp_code_Finger_Server= 73 ,/**< Finger-Server N Finger Server Addresses [RFC2132] */
+ dhcp_code_IRC_Server= 74 ,/**< IRC-Server N Chat Server Addresses [RFC2132] */
+ dhcp_code_StreetTalk_Server= 75 ,/**< StreetTalk-Server N StreetTalk Server Addresses [RFC2132] */
+ dhcp_code_STDA_Server= 76 ,/**< STDA-Server N ST Directory Assist. Addresses [RFC2132] */
+ dhcp_code_User_Class= 77 ,/**< User-Class N User Class Information [RFC3004] */
+ dhcp_code_Directory_Agent = 78 ,/**< Directory Agent N directory agent information [RFC2610] */
+ dhcp_code_Service_Scope = 79 ,/**< Service Scope N service location agent scope [RFC2610] */
+ dhcp_code_Rapid_Commit= 80 ,/**< Rapid Commit 0 Rapid Commit [RFC4039] */
+ dhcp_code_Client_FQDN = 81 ,/**< Client FQDN N Fully Qualified Domain Name [RFC4702] */
+ dhcp_code_Relay_Agent_Information= 82 ,/**< Relay Agent Information N Relay Agent Information [RFC3046] */
+ dhcp_code_iSNS= 83 ,/**< iSNS N Internet Storage Name Service [RFC4174] */
+ //84 REMOVED/Unassigned [RFC3679] */
+ dhcp_code_NDS_Servers= 85 ,/**< NDS Servers N Novell Directory Services [RFC2241] */
+ dhcp_code_NDS_Tree_Name= 86 ,/**< NDS Tree Name N Novell Directory Services [RFC2241] */
+ dhcp_code_NDS_Context= 87 ,/**< NDS Context N Novell Directory Services [RFC2241] */
+ dhcp_code_BCMCS_Controller_Domain_Name_list= 88 ,/**< BCMCS Controller Domain Name list [RFC4280] */
+ dhcp_code_BCMCS_Controller_IPv4_address_option= 89 ,/**< BCMCS Controller IPv4 address option [RFC4280] */
+ dhcp_code_Authentication= 90 ,/**< Authentication N Authentication [RFC3118] */
+ dhcp_code_client_last_transaction_time= 91 ,/**< client-last-transaction-time option [RFC4388] */
+ dhcp_code_associated_ip= 92 ,/**< associated-ip option [RFC4388] */
+ dhcp_code_Client_System = 93 ,/**< Client System N Client System Architecture [RFC4578] */
+ dhcp_code_Client_NDI = 94 ,/**< Client NDI N Client Network Device Interface [RFC4578] */
+ dhcp_code_LDAP= 95 ,/**< LDAP N Lightweight Directory Access Protocol [RFC3679] */
+ dhcp_code_REMOVED_Unassigned= 96 ,/**< REMOVED/Unassigned [RFC3679] */
+ dhcp_code_UUID_GUID= 97 ,/**< UUID/GUID N UUID/GUID-based Client Identifier [RFC4578] */
+ dhcp_code_User_Auth= 98 ,/**< User-Auth N Open Group's User Authentication [RFC2485] */
+ dhcp_code_GEOCONF_CIVIC= 99 ,/**< GEOCONF_CIVIC [RFC4776] */
+ dhcp_code_PCode= 100 ,/**< PCode N IEEE 1003.1 TZ String [RFC4833] */
+ dhcp_code_TCode= 101 ,/**< TCode N Reference to the TZ Database [RFC4833] */
+ //102-107 REMOVED/Unassigned [RFC3679]
+ //108 REMOVED/Unassigned [RFC3679]
+ //109 Unassigned [RFC3679]
+ //110 REMOVED/Unassigned [RFC3679]
+ //111 Unassigned [RFC3679]
+ dhcp_code_Netinfo_Address= 112 ,/**< Netinfo Address N NetInfo Parent Server Address [RFC3679] */
+ dhcp_code_Netinfo_Tag= 113 ,/**< Netinfo Tag N NetInfo Parent Server Tag [RFC3679] */
+ dhcp_code_= 114 ,/**< URL N URL [RFC3679] */
+ //115 REMOVED/Unassigned [RFC3679]
+ dhcp_code_Auto_Config= 116 ,/**< Auto-Config N DHCP Auto-Configuration [RFC2563] */
+ dhcp_code_Name_Service_Search= 117 ,/**< Name Service Search N Name Service Search [RFC2937] */
+ dhcp_code_Subnet_Selection_Option= 118 ,/**< Subnet Selection Option 4 Subnet Selection Option [RFC3011] */
+ dhcp_code_Domain_Search= 119 ,/**< Domain Search N DNS domain search list [RFC3397] */
+ dhcp_code_SIP_Servers_DHCP_Option= 120 ,/**< SIP Servers DHCP Option N SIP Servers DHCP Option [RFC3361] */
+ dhcp_code_Classless_Static_Route_Option= 121 ,/**< Classless Static Route Option N Classless Static Route Option [RFC3442] */
+ dhcp_code_CCC= 122 ,/**< CCC N CableLabs Client Configuration [RFC3495] */
+ dhcp_code_GeoConf_Option= 123 ,/**< GeoConf Option 16 GeoConf Option [RFC3825] */
+ dhcp_code_V_I_Vendor_Class= 124 ,/**< V-I Vendor Class Vendor-Identifying Vendor Class [RFC3925] */
+ dhcp_code_V_I_Vendor_Specific_Information= 125 ,/**< V-I Vendor-Specific Information Vendor-Identifying Vendor-Specific Information [RFC3925] */
+ //dhcp_code_= 126 ,/**< Removed/Unassigned [RFC3679] */
+ //dhcp_code_= 127 ,/**< Removed/Unassigned [RFC3679] */
+ //dhcp_code_PXE - undefined= 128 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_Etherboot_signature= 128 ,/**< Etherboot signature. 6 bytes: E4:45:74:68:00:00 */
+ dhcp_code_DOCSIS= 128 ,/**< DOCSIS "full security" server IP address */
+ dhcp_code_TFTP_Server_IP= 128 ,/**< TFTP Server IP address (for IP Phone software load) */
+ //dhcp_code_= 129 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_Kernel_options= 129 ,/**< Kernel options. Variable length string */
+ dhcp_code_Call_Server_IP= 129 ,/**< Call Server IP address */
+ //dhcp_code_= 130 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_Ethernet_interface= 130 ,/**< Ethernet interface. Variable length string. */
+ dhcp_code_Discrimination= 130 ,/**< Discrimination string (to identify vendor) */
+ //dhcp_code_= 131 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_Remote_statistics_server_IP= 131 ,/**< Remote statistics server IP address */
+ //dhcp_code_= 132 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_IEEE_802_1Q_VLAN_ID= 132 ,/**< IEEE 802.1Q VLAN ID */
+ //dhcp_code_= 133 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_IEEE_802_1D_p= 133 ,/**< IEEE 802.1D/p Layer 2 Priority */
+ //dhcp_code_= 134 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_DSCP= 134 ,/**< Diffserv Code Point (DSCP) for VoIP signalling and media streams */
+ //dhcp_code_= 135 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_HTTP_Proxy= 135 ,/**< HTTP Proxy for phone-specific applications */
+ dhcp_code_OPTION_PANA_AGENT= 136 ,/**< OPTION_PANA_AGENT [RFC5192] */
+ dhcp_code_OPTION_V4_LOST= 137 ,/**< OPTION_V4_LOST [RFC5223] */
+ dhcp_code_OPTION_CAPWAP_AC_V4= 138 ,/**< OPTION_CAPWAP_AC_V4 N CAPWAP Access Controller addresses [RFC5417] */
+ dhcp_code_OPTION_IPv4_Address_MoS= 139 ,/**< OPTION-IPv4_Address-MoS N a series of suboptions [RFC5678] */
+ dhcp_code_OPTION_IPv4_FQDN_MoS= 140 ,/**< OPTION-IPv4_FQDN-MoS N a series of suboptions [RFC5678] */
+ //141-149 Unassigned [RFC3942] */
+ dhcp_code_TFTP_server_address= 150 ,/**< TFTP server address (Tentatively Assigned - 2005-06-23) */
+ dhcp_code_Etherboot= 150 ,/**< Etherboot */
+ dhcp_code_GRUB_configuration_path_name= 150 ,/**< GRUB configuration path name */
+ //151-174 Unassigned [RFC3942]
+ //dhcp_code_Etherboot= 175 ,/**< Etherboot (Tentatively Assigned - 2005-06-23) */
+ dhcp_code_IP_Telephone= 176 ,/**< IP Telephone (Tentatively Assigned - 2005-06-23) */
+ //dhcp_code_Etherboot= 177 ,/**< Etherboot (Tentatively Assigned - 2005-06-23) */
+ dhcp_code_PacketCable_and_CableHome= 177 ,/**< PacketCable and CableHome (replaced by 122) */
+ //178-207 Unassigned [RFC3942]
+ dhcp_code_PXELINUX_Magic= 208 ,/**< PXELINUX Magic 4 magic string = F1:00:74:7E [RFC5071] Deprecated */
+ dhcp_code_Configuration_File= 209 ,/**< Configuration File N Configuration file [RFC5071] */
+ dhcp_code_Path_Prefix= 210 ,/**< Path Prefix N Path Prefix Option [RFC5071] */
+ dhcp_code_Reboot_Time = 211 ,/**< Reboot Time 4 Reboot Time [RFC5071] */
+ // 212-219 Unassigned
+ dhcp_code_Subnet_Allocation= 220 ,/**< Subnet Allocation Option (Tentatively Assigned - 2005-06-23) */
+ dhcp_code_Virtual_Subnet= 221 ,/**< Virtual Subnet Selection Option (Tentatively Assigned - 2005-06-23) */
+ // 222-223 Unassigned [RFC3942]
+ //224-254 Reserved (Private Use)
+ dhcp_code_null=224 ,
+ dhcp_code_End= 255 ,/**< End 0 None [RFC2132] */
+}
+tnet_dhcp_option_code_t;
+
+/** DHCP/BOOTP option as per RFC 2132.
+* Format ==> subclause 2.
+*/
+typedef struct tnet_dhcp_option_s
+{
+ TSK_DECLARE_OBJECT;
+
+ tsk_bool_t initialized;
+
+ tnet_dhcp_option_code_t code; /**< 1-byte option-code. */
+ tsk_buffer_t *value;
+}
+tnet_dhcp_option_t;
+
+typedef tsk_list_t tnet_dhcp_options_L_t;
+
+#define TNET_DECLARE_DHCP_OPTION tnet_dhcp_option_t dhcp_option
+
+int tnet_dhcp_option_init(tnet_dhcp_option_t *self, tnet_dhcp_option_code_t code);
+int tnet_dhcp_option_deinit(tnet_dhcp_option_t *self);
+
+tnet_dhcp_option_t* tnet_dhcp_option_deserialize(const void* data, tsk_size_t size);
+int tnet_dhcp_option_serialize(const tnet_dhcp_option_t* self, tsk_buffer_t *output);
+int tnet_dhcp_option_serializeex(tnet_dhcp_option_code_t code, uint8_t length, const void* value, tsk_buffer_t *output);
+
+/*=======================================================================================
+* RFC 2132 - 9.8. Parameter Request List
+*=======================================================================================*/
+
+/** Parameter Request List Option */
+typedef struct tnet_dhcp_option_paramslist_s
+{
+ TNET_DECLARE_DHCP_OPTION;
+
+ /* RFC 2132 - 9.8. Parameter Request List
+ Code Len Option Codes
+ +-----+-----+-----+-----+---
+ | 55 | n | c1 | c2 | ...
+ +-----+-----+-----+-----+---
+ */
+}
+tnet_dhcp_option_paramslist_t;
+int tnet_dhcp_option_paramslist_add_code(tnet_dhcp_option_paramslist_t* self, tnet_dhcp_option_code_t code);
+
+/*=======================================================================================
+* RFC 2132 - 3.8. Domain Name Server Option
+*=======================================================================================*/
+
+/** Domain Name Server Option */
+typedef struct tnet_dhcp_option_dns_s
+{
+ TNET_DECLARE_DHCP_OPTION;
+
+ /* RFC 2132 - 3.8. Domain Name Server Option
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ tsk_strings_L_t *servers;
+}
+tnet_dhcp_option_dns_t;
+
+TINYNET_API tnet_dhcp_option_t* tnet_dhcp_option_create(tnet_dhcp_option_code_t code);
+TINYNET_API tnet_dhcp_option_paramslist_t* tnet_dhcp_option_paramslist_create();
+TINYNET_API tnet_dhcp_option_dns_t* tnet_dhcp_option_dns_create(const void* payload, tsk_size_t payload_size);
+
+TINYNET_GEXTERN const tsk_object_def_t *tnet_dhcp_option_def_t;
+TINYNET_GEXTERN const tsk_object_def_t *tnet_dns_ns_def_t;
+TINYNET_GEXTERN const tsk_object_def_t *tnet_dhcp_option_paramslist_def_t;
+TINYNET_GEXTERN const tsk_object_def_t *tnet_dhcp_option_dns_def_t;
+
+
+TNET_END_DECLS
+
+#endif /* TNET_DHCP_OPTION_H */
diff --git a/tinyNET/src/dhcp/tnet_dhcp_option_sip.c b/tinyNET/src/dhcp/tnet_dhcp_option_sip.c
new file mode 100644
index 0000000..69d564e
--- /dev/null
+++ b/tinyNET/src/dhcp/tnet_dhcp_option_sip.c
@@ -0,0 +1,131 @@
+/*
+* Copyright (C) 2009-2010 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+/**@file tnet_dhcp_option_sip.c
+ * @brief Dynamic Host Configuration Protocol (DHCP-for-IPv4) Option for
+ * Session Initiation Protocol (SIP) Servers as per RFC 3361.
+ *
+ * @author Mamadou Diop <diopmamadou(at)doubango.org>
+ *
+ * @date Created: Sat Nov 8 16:54:58 2009 mdiop
+ */
+#include "tnet_dhcp_option_sip.h"
+
+#include "dns/tnet_dns_rr.h"
+
+#include "../tnet_types.h"
+#include "../tnet_endianness.h"
+
+#include "tsk_memory.h"
+#include "tsk_string.h"
+
+tnet_dhcp_option_sip_t* tnet_dhcp_option_sip_create(const void* payload, tsk_size_t payload_size)
+{
+ return tsk_object_new(tnet_dhcp_option_sip_def_t, payload, payload_size);
+}
+
+//
+// [[DHCP SIP4]] object definition
+//
+static tsk_object_t* tnet_dhcp_option_sip_ctor(tsk_object_t * self, va_list * app)
+{
+ tnet_dhcp_option_sip_t *option = self;
+ if(option){
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ const uint8_t* payloadPtr = (const uint8_t*)payload;
+ const uint8_t* payloadEnd = (payloadPtr + payload_size);
+
+ /* init base */
+ tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_SIP_Servers_DHCP_Option);
+
+ option->servers = tsk_list_create();
+
+ /* Set values as per RFC 3361. */
+ if(*payloadPtr == 0){ /* enc=0 */
+ /*
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ |120|27 | 0 | 7 |'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'c'|'o'|'m'| 0 |
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+ | 7
+ |'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'n'|'e'|'t'| 0 | +---+---+---
+ +---+---+---+---+---+---+---+---+---+---+
+ */
+ tsk_size_t offset = 1;
+ char* server = 0;
+ payloadPtr++;
+ while((payloadPtr < payloadEnd) && !tnet_dns_rr_qname_deserialize(payload, &server, &offset)){
+ tsk_string_t* string = tsk_string_create(server);
+ tsk_list_push_back_data(option->servers, (void*)&string);
+ TSK_FREE(server);
+ payloadPtr += offset;
+ }
+ }
+ else{
+ /*
+ Code Len enc Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 120 | n | 1 | a1 | a2 | a3 | a4 | a1 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ uint32_t address;
+ tsk_string_t* addrstring;
+ char* ip4 = 0;
+
+ while(payloadPtr < payloadEnd){
+ ++payloadPtr;
+ address = tnet_htonl_2(payloadPtr);
+
+ tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
+
+ addrstring = tsk_string_create(ip4);
+ tsk_list_push_back_data(option->servers, (void*)&addrstring);
+
+ TSK_FREE(ip4);
+
+ payloadPtr+= 4;
+ }
+ }
+ }
+ return self;
+}
+
+static tsk_object_t* tnet_dhcp_option_sip_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_option_sip_t *option = self;
+ if(option){
+ /* deinit base */
+ tnet_dhcp_option_deinit(TNET_DHCP_OPTION(option));
+
+ TSK_OBJECT_SAFE_FREE(option->servers);
+ }
+ return self;
+}
+
+static const tsk_object_def_t tnet_dhcp_option_sip_def_s =
+{
+ sizeof(tnet_dhcp_option_sip_t),
+ tnet_dhcp_option_sip_ctor,
+ tnet_dhcp_option_sip_dtor,
+ tsk_null,
+};
+const tsk_object_def_t *tnet_dhcp_option_sip_def_t = &tnet_dhcp_option_sip_def_s;
diff --git a/tinyNET/src/dhcp/tnet_dhcp_option_sip.h b/tinyNET/src/dhcp/tnet_dhcp_option_sip.h
new file mode 100644
index 0000000..8db7049
--- /dev/null
+++ b/tinyNET/src/dhcp/tnet_dhcp_option_sip.h
@@ -0,0 +1,62 @@
+/*
+* Copyright (C) 2009-2010 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+/**@file tnet_dhcp_option_sip.h
+ * @brief Dynamic Host Configuration Protocol (DHCP-for-IPv4) Option for
+ * Session Initiation Protocol (SIP) Servers as per RFC 3361.
+ *
+ * @author Mamadou Diop <diopmamadou(at)doubango.org>
+ *
+ * @date Created: Sat Nov 8 16:54:58 2009 mdiop
+ */
+
+#ifndef tnet_dhcp_option_sip_H
+#define tnet_dhcp_option_sip_H
+
+#include "tinynet_config.h"
+
+#include "tnet_dhcp_option.h"
+
+#include "tsk_string.h"
+
+TNET_BEGIN_DECLS
+
+typedef struct tnet_dhcp_option_sip_s
+{
+ TNET_DECLARE_DHCP_OPTION;
+
+ /* RFC 3361 subclause 3.1
+ Code Len enc DNS name of SIP server
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 120 | n | 0 | s1 | s2 | s3 | s4 | s5 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ tsk_strings_L_t *servers;
+}
+tnet_dhcp_option_sip_t;
+
+TINYNET_API tnet_dhcp_option_sip_t* tnet_dhcp_option_sip_create(const void* payload, tsk_size_t payload_size);
+
+TINYNET_GEXTERN const tsk_object_def_t *tnet_dhcp_option_sip_def_t;
+
+TNET_END_DECLS
+
+#endif /* #define tnet_dhcp_option_sip_H */
OpenPOWER on IntegriCloud