Initial DHCP encode/decode draft

This commit is contained in:
Christian Giese
2021-04-23 20:38:36 +02:00
parent b4521f8fb9
commit 3ea8883634
2 changed files with 326 additions and 1 deletions
+181 -1
View File
@@ -184,6 +184,90 @@ encode_dhcpv6(uint8_t *buf, uint16_t *len,
return PROTOCOL_SUCCESS;
}
/*
* encode_dhcp
*/
protocol_error_t
encode_dhcp(uint8_t *buf, uint16_t *len,
bbl_dhcp_t *dhcp) {
if(!dhcp->header) return ENCODE_ERROR;
uint8_t *option_len;
memcpy(buf, dhcp->header, sizeof(struct dhcp_header));
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
*buf = DHCPV4_OPTION_DHCP_MESSAGE_TYPE;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*buf = 1;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*buf = dhcp->type;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
if(dhcp->parameter_request_list) {
*buf = DHCPV4_OPTION_PARAM_REQUEST_LIST;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
option_len = buf; /* option len */
*option_len = 0;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
if(dhcp->option_netmask) {
*option_len = *option_len+1;
*buf = DHCPV4_OPTION_SUBNET_MASK;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
}
if(dhcp->option_router) {
*option_len = *option_len+1;
*buf = DHCPV4_OPTION_ROUTER;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
}
if(dhcp->option_dns1 || dhcp->option_dns2) {
*option_len = *option_len+1;
*buf = DHCPV4_OPTION_DNS_SERVER;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
}
if(dhcp->option_domain_name) {
*option_len = *option_len+1;
*buf = DHCPV4_OPTION_DOMAIN_NAME;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
}
}
if(dhcp->client_identifier) {
*buf = DHCPV4_OPTION_CLIENT_IDENTIFIER;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*buf = dhcp->client_identifier_len;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
memcpy(buf, dhcp->client_identifier, dhcp->client_identifier_len);
BUMP_WRITE_BUFFER(buf, len, dhcp->client_identifier_len);
}
if(dhcp->server_identifier) {
*buf = DHCPV4_OPTION_SERVER_IDENTIFIER;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*buf = dhcp->server_identifier_len;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
memcpy(buf, dhcp->server_identifier, dhcp->server_identifier_len);
BUMP_WRITE_BUFFER(buf, len, dhcp->server_identifier_len);
}
if(dhcp->option_address) {
*buf = DHCPV4_OPTION_REQUESTED_IP_ADDRESS;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*buf = 4;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*(uint32_t*)buf = dhcp->address;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
}
*buf = DHCPV4_OPTION_END;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
/* This is optional ... */
while(*len % 8) {
*buf = DHCPV4_OPTION_PAD;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
}
return PROTOCOL_SUCCESS;
}
/*
* encode_bbl
*/
@@ -1432,7 +1516,7 @@ decode_dhcpv6(uint8_t *buf, uint16_t len,
return DECODE_ERROR;
}
/* Init IPv4 header */
/* Init DHCPv6 structure */
dhcpv6 = (bbl_dhcpv6_t*)sp; BUMP_BUFFER(sp, sp_len, sizeof(bbl_dhcpv6_t));
memset(dhcpv6, 0x0, sizeof(bbl_dhcpv6_t));
@@ -1488,6 +1572,102 @@ decode_dhcpv6(uint8_t *buf, uint16_t len,
return ret_val;
}
/*
* decode_dhcp
*/
protocol_error_t
decode_dhcp(uint8_t *buf, uint16_t len,
uint8_t *sp, uint16_t sp_len,
bbl_dhcp_t **_dhcp) {
protocol_error_t ret_val = PROTOCOL_SUCCESS;
bbl_dhcp_t *dhcp;
uint8_t option;
uint8_t option_len;
if(len < sizeof(struct dhcp_header) || sp_len < sizeof(bbl_dhcp_t)) {
return DECODE_ERROR;
}
/* Init DHCP structure */
dhcp = (bbl_dhcp_t*)sp; BUMP_BUFFER(sp, sp_len, sizeof(bbl_dhcp_t));
memset(dhcp, 0x0, sizeof(bbl_dhcp_t));
dhcp->header = (struct dhcp_header*)buf;
BUMP_BUFFER(buf, len, sizeof(struct dhcp_header));
while(len >= 2) {
option = *buf;
BUMP_BUFFER(buf, len, sizeof(uint8_t));
if(option == DHCPV4_OPTION_PAD) {
continue;
}
option_len = *buf;
BUMP_BUFFER(buf, len, sizeof(uint16_t));
if(option_len > len) {
return DECODE_ERROR;
}
switch(option) {
case DHCPV4_OPTION_END:
option_len = len;
break;
case DHCPV4_OPTION_DHCP_MESSAGE_TYPE:
if(option_len != 1) {
return DECODE_ERROR;
}
dhcp->type = *buf;
break;
case DHCPV4_OPTION_SUBNET_MASK:
if(option_len != 4) {
return DECODE_ERROR;
}
dhcp->netmask = *(uint32_t*)buf;
dhcp->option_netmask = true;
break;
case DHCPV4_OPTION_ROUTER:
if(option_len < 4) {
return DECODE_ERROR;
}
dhcp->router = *(uint32_t*)buf;
dhcp->option_router = true;
break;
case DHCPV4_OPTION_DNS_SERVER:
if(option_len < 4) {
return DECODE_ERROR;
}
dhcp->dns1 = *(uint32_t*)buf;
dhcp->option_dns1 = true;
if(option_len >=8) {
dhcp->dns2 = *(uint32_t*)(buf+4);
dhcp->option_dns2 = true;
}
break;
case DHCPV4_OPTION_HOST_NAME:
dhcp->host_name = (char*)buf;
dhcp->host_name_len = option_len;
break;
case DHCPV4_OPTION_DOMAIN_NAME:
dhcp->domain_name = (char*)buf;
dhcp->domain_name_len = option_len;
break;
case DHCPV4_OPTION_INTERFACE_MTU:
if(option_len != 2) {
return DECODE_ERROR;
}
dhcp->mtu = be16toh(*(uint16_t*)buf);
dhcp->option_mtu = true;
break;
default:
break;
}
BUMP_BUFFER(buf, len, option_len);
}
*_dhcp = dhcp;
return ret_val;
}
/*
* decode_bbl
*/
+145
View File
@@ -297,6 +297,99 @@ typedef enum dhcpv6_option_code_ {
DHCPV6_OPTION_MAX,
} dhcpv6_option_code;
typedef enum dhcp_message_type_ {
DHCPV4_MESSAGE_DISCOVER = 1,
DHCPV4_MESSAGE_OFFER = 2,
DHCPV4_MESSAGE_REQUEST = 3,
DHCPV4_MESSAGE_DECLINE = 4,
DHCPV4_MESSAGE_ACK = 5,
DHCPV4_MESSAGE_NAK = 6,
DHCPV4_MESSAGE_RELEASE = 7,
DHCPV4_MESSAGE_INFORM = 8,
DHCPV4_MESSAGE_MAX
} dhcp_message_type;
typedef enum dhcp_option_code_ {
DHCPV4_OPTION_PAD = 0,
DHCPV4_OPTION_SUBNET_MASK = 1,
DHCPV4_OPTION_TIME_OFFSET = 2,
DHCPV4_OPTION_ROUTER = 3,
DHCPV4_OPTION_TIME_SERVER = 4,
DHCPV4_OPTION_NAME_SERVER = 5,
DHCPV4_OPTION_DNS_SERVER = 6,
DHCPV4_OPTION_LOG_SERVER = 7,
DHCPV4_OPTION_COOKIE_SERVER = 8,
DHCPV4_OPTION_LPR_SERVER = 9,
DHCPV4_OPTION_IMPRESS_SERVER = 10,
DHCPV4_OPTION_RESOURCE_LOCATION_SERVER = 11,
DHCPV4_OPTION_HOST_NAME = 12,
DHCPV4_OPTION_BOOT_FILE_SIZE = 13,
DHCPV4_OPTION_MERIT_DUMP_FILE = 14,
DHCPV4_OPTION_DOMAIN_NAME = 15,
DHCPV4_OPTION_SWAP_SERVER = 16,
DHCPV4_OPTION_ROOT_PATH = 17,
DHCPV4_OPTION_EXTENSIONS_PATH = 18,
DHCPV4_OPTION_IP_FORWARDING = 19,
DHCPV4_OPTION_NON_LOCAL_SOURCE_ROUTING = 20,
DHCPV4_OPTION_POLICY_FILTER = 21,
DHCPV4_OPTION_MAX_DATAGRAM_REASSEMBLY_SIZE = 22,
DHCPV4_OPTION_DEFAULT_IP_TTL = 23,
DHCPV4_OPTION_PATH_MTU_AGING_TIMEOUT = 24,
DHCPV4_OPTION_PATH_MTU_PLATEAU_TABLE = 25,
DHCPV4_OPTION_INTERFACE_MTU = 26,
DHCPV4_OPTION_ALL_SUBNETS_ARE_LOCAL = 27,
DHCPV4_OPTION_BROADCAST_ADDRESS = 28,
DHCPV4_OPTION_PERFORM_MASK_DISCOVERY = 29,
DHCPV4_OPTION_MASK_SUPPLIER = 30,
DHCPV4_OPTION_PERFORM_ROUTER_DISCOVERY = 31,
DHCPV4_OPTION_ROUTER_SOLICITATION_ADDRESS = 32,
DHCPV4_OPTION_STATIC_ROUTE = 33,
DHCPV4_OPTION_TRAILER_ENCAPSULATION = 34,
DHCPV4_OPTION_ARP_CACHE_TIMEOUT = 35,
DHCPV4_OPTION_ETHERNET_ENCAPSULATION = 36,
DHCPV4_OPTION_TCP_DEFAULT_TTL = 37,
DHCPV4_OPTION_TCP_KEEPALIVE_INTERVAL = 38,
DHCPV4_OPTION_TCP_KEEPALIVE_GARBAGE = 39,
DHCPV4_OPTION_NIS_DOMAIN = 40,
DHCPV4_OPTION_NIS_SERVER = 41,
DHCPV4_OPTION_NTP_SERVER = 42,
DHCPV4_OPTION_VENDOR_SPECIFIC_INFO = 43,
DHCPV4_OPTION_NETBIOS_NBNS_SERVER = 44,
DHCPV4_OPTION_NETBIOS_NBDD_SERVER = 45,
DHCPV4_OPTION_NETBIOS_NODE_TYPE = 46,
DHCPV4_OPTION_NETBIOS_SCOPE = 47,
DHCPV4_OPTION_X11_FONT_SERVER = 48,
DHCPV4_OPTION_X11_DISPLAY_MANAGER = 49,
DHCPV4_OPTION_REQUESTED_IP_ADDRESS = 50,
DHCPV4_OPTION_IP_ADDRESS_LEASE_TIME = 51,
DHCPV4_OPTION_OPTION_OVERLOAD = 52,
DHCPV4_OPTION_DHCP_MESSAGE_TYPE = 53,
DHCPV4_OPTION_SERVER_IDENTIFIER = 54,
DHCPV4_OPTION_PARAM_REQUEST_LIST = 55,
DHCPV4_OPTION_MESSAGE = 56,
DHCPV4_OPTION_MAX_DHCP_MESSAGE_SIZE = 57,
DHCPV4_OPTION_RENEWAL_TIME_VALUE = 58,
DHCPV4_OPTION_REBINDING_TIME_VALUE = 59,
DHCPV4_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
DHCPV4_OPTION_CLIENT_IDENTIFIER = 61,
DHCPV4_OPTION_NISP_DOMAIN = 64,
DHCPV4_OPTION_NISP_SERVER = 65,
DHCPV4_OPTION_TFTP_SERVER_NAME = 66,
DHCPV4_OPTION_BOOTFILE_NAME = 67,
DHCPV4_OPTION_MOBILE_IP_HOME_AGENT = 68,
DHCPV4_OPTION_SMTP_SERVER = 69,
DHCPV4_OPTION_POP3_SERVER = 70,
DHCPV4_OPTION_NNTP_SERVER = 71,
DHCPV4_OPTION_DEFAULT_WWW_SERVER = 72,
DHCPV4_OPTION_DEFAULT_FINGER_SERVER = 73,
DHCPV4_OPTION_DEFAULT_IRC_SERVER = 74,
DHCPV4_OPTION_STREETTALK_SERVER = 75,
DHCPV4_OPTION_STDA_SERVER = 76,
DHCPV4_OPTION_RAPID_COMMIT = 80,
DHCPV4_OPTION_CAPTIVE_PORTAL = 160,
DHCPV4_OPTION_END = 255
} dhcp_option_code;
typedef enum access_line_codes_ {
// broadband forum tr101
ACCESS_LINE_ACI = 0x01, // Agent Circuit ID
@@ -575,6 +668,58 @@ typedef struct bbl_dhcpv6_ {
ipv6addr_t *dns2;
} bbl_dhcpv6_t;
struct dhcp_header {
uint8_t op;
uint8_t htype;
uint8_t hlen;
uint8_t hops;
uint32_t xid;
uint16_t secs;
uint16_t flags;
uint32_t ciaddr;
uint32_t yiaddr;
uint32_t siaddr;
uint32_t giaddr;
char chaddr[16];
char sname[64];
char file[128];
uint32_t magic_cookie;
} __attribute__ ((__packed__));
typedef struct bbl_dhcp_ {
const struct dhcp_header *header;
uint8_t type;
uint8_t *server_identifier;
uint8_t server_identifier_len;
uint8_t *client_identifier;
uint8_t client_identifier_len;
uint32_t lease_time;
uint32_t address;
uint32_t netmask;
uint32_t dns1;
uint32_t dns2;
uint32_t router;
uint16_t mtu;
char *host_name;
uint8_t host_name_len;
char *domain_name;
uint8_t domain_name_len;
bool parameter_request_list;
bool option_lease_time;
bool option_address;
bool option_netmask;
bool option_dns1;
bool option_dns2;
bool option_router;
bool option_mtu;
bool option_host_name;
bool option_domain_name;
} bbl_dhcp_t;
typedef struct bbl_l2tp_ {
bool with_length; // L Bit
bool with_sequence; // S Bit