diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 4f4afe6746e..aafd459f869 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1351,8 +1351,20 @@ struct ndpi_flow_struct { } bittorrent; struct { - char fingerprint[48]; - char class_ident[48]; + u_int32_t xid; + u_int32_t yiaddr; + u_int32_t siaddr; + u_int8_t chaddr[6]; + /* DHCP Options */ + char domain_name[256]; /* option 15 limited to 255 chars see RFC 1035 */ + u_int32_t requested_ip; /* option 50 */ + u_int32_t lease_time; /* option 51 */ + u_int8_t msg_type; /* option 53 */ + u_int8_t valid; /* signifies valid dhcp resp itmap for valid ip addr options as well 50,54 */ + ndpi_ip_addr_t server_ident; /* option 54 */ + char fingerprint[48]; /* option 55 */ + u_int32_t renew_time; /* option 58 */ + char class_ident[48]; /* option 60 */ } dhcp; struct { diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c index 5c59f699994..c7b31e236d1 100644 --- a/src/lib/protocols/dhcp.c +++ b/src/lib/protocols/dhcp.c @@ -92,7 +92,6 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, u_int dhcp_options_size = ndpi_min(DHCP_VEND_LEN /* maximum size of options in struct dhcp_packet */, packet->payload_packet_len - 240); - /* Parse options in two steps (since we need first the message type and it seems there is no specific order in the options list) */ @@ -114,6 +113,7 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, if(msg_type <= 8) { foundValidMsgType = 1; + flow->protos.dhcp.valid |= 0x01; break; } } @@ -133,7 +133,13 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, /* Ok, we have a valid DHCP packet -> we can write to flow->protos.dhcp */ NDPI_LOG_INFO(ndpi_struct, "found DHCP\n"); ndpi_int_dhcp_add_connection(ndpi_struct, flow); - + + /* Assign basic dhcp information to flow structure */ + flow->protos.dhcp.msg_type = msg_type; /* option 53 msg_type */ + flow->protos.dhcp.xid = dhcp->xid; + flow->protos.dhcp.siaddr = dhcp->siaddr; + flow->protos.dhcp.yiaddr = dhcp->yiaddr; + memcpy(flow->protos.dhcp.chaddr, dhcp->chaddr, sizeof(dhcp->chaddr)); /* Second iteration: parse the interesting options */ while(i + 1 /* for the len */ < dhcp_options_size) { u_int8_t id = dhcp->options[i]; @@ -180,8 +186,24 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, // while(j < len) { printf( "%c", name[j]); j++; }; printf("\n"); #endif ndpi_hostname_sni_set(flow, name, len); - } - + } else if(id == 15 /* Domain Name */) { + char *name = (char*)&dhcp->options[i+2]; + int j = 0; + + j = ndpi_min(len, sizeof(flow->protos.dhcp.domain_name)-1); + strncpy((char*)flow->protos.dhcp.domain_name, name, j); + flow->protos.dhcp.domain_name[j] = '\0'; + } else if(id == 50) /* Requested IP */ { + flow->protos.dhcp.valid |= 0x02 ; + memcpy(&flow->protos.dhcp.requested_ip, (char*)&dhcp->options[i+2], ndpi_min(sizeof(flow->protos.dhcp.requested_ip), len)); + } else if(id == 51) /* Lease Time */ { + memcpy(&flow->protos.dhcp.lease_time, (char*)&dhcp->options[i+2], ndpi_min(sizeof(flow->protos.dhcp.lease_time),len)); + } else if(id == 54) /* Server Identifier */ { + flow->protos.dhcp.valid |= 0x04; + memcpy(&flow->protos.dhcp.server_ident, (char*)&dhcp->options[i+2], ndpi_min(sizeof(flow->protos.dhcp.server_ident), len)); + } else if(id == 58) /* Renewal Time */ { + memcpy(&flow->protos.dhcp.renew_time, (char*)&dhcp->options[i+2], ndpi_min(sizeof(flow->protos.dhcp.renew_time), len)); + } i += len + 2; } }