From 117dce93be0bd9bf540c3daa62391407cc690292 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 19 Feb 2021 10:25:03 +0100 Subject: Initial commit --- a.out | Bin 0 -> 22208 bytes dhcp_probe.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++++ dhcp_probe.cflags | 1 + dhcp_probe.config | 2 + dhcp_probe.creator | 1 + dhcp_probe.creator.user | 227 +++++++++++++++++++++++++++++++++++++++++++ dhcp_probe.cxxflags | 1 + dhcp_probe.files | 1 + dhcp_probe.includes | 0 9 files changed, 483 insertions(+) create mode 100755 a.out create mode 100644 dhcp_probe.c create mode 100644 dhcp_probe.cflags create mode 100644 dhcp_probe.config create mode 100644 dhcp_probe.creator create mode 100644 dhcp_probe.creator.user create mode 100644 dhcp_probe.cxxflags create mode 100644 dhcp_probe.files create mode 100644 dhcp_probe.includes diff --git a/a.out b/a.out new file mode 100755 index 0000000..04bc884 Binary files /dev/null and b/a.out differ diff --git a/dhcp_probe.c b/dhcp_probe.c new file mode 100644 index 0000000..03bde74 --- /dev/null +++ b/dhcp_probe.c @@ -0,0 +1,250 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//TODO: Name DHCPPROBE' + +#define BROADCAST_ADDRESS "255.255.255.255" + +#define MAX_DHCP_CHADDR_LENGTH 16 +#define MAX_DHCP_SNAME_LENGTH 64 +#define MAX_DHCP_FILE_LENGTH 128 +#define DHCP_MAGIC_LENGTH 4 +#define MAX_DHCP_OPTIONS_LENGTH 312 - DHCP_MAGIC_LENGTH + +typedef struct dhcp_packet +{ + 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; + uint8_t chaddr[MAX_DHCP_CHADDR_LENGTH]; + uint8_t sname[MAX_DHCP_SNAME_LENGTH]; + uint8_t file[MAX_DHCP_FILE_LENGTH]; + uint8_t magic[DHCP_MAGIC_LENGTH]; + uint8_t opt[MAX_DHCP_OPTIONS_LENGTH]; +} __attribute__((__packed__)) dhcp_packet_t; + +static int fill_mac_address(uint8_t* base_addr, const char* interface_name) +{ + int fd; + struct ifreq ifr; + + if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) + exit(1); + + strcpy(ifr.ifr_name, interface_name); + + if(ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) + exit(1); + + close(fd); + + memcpy(base_addr, ifr.ifr_addr.sa_data, 6); + + return 0; +} + +static int construct_dhcp_discover(dhcp_packet_t* packet, const char* iface_name) +{ + srand(time(NULL)); + + packet->op = 1; //request + packet->htype = 6; //wifi + packet->hlen = 6; //default + packet->hops = 0; + packet->xid = htonl(rand()); //random + packet->secs = htons(0); + packet->flags = htons(0x8000); //dont know my own ip, so send back by broadcast + packet->ciaddr = 0; //my ip address + packet->yiaddr = 0; //my future ip address + packet->siaddr = 0; //server address + packet->giaddr = 0; //gateway address + + if(fill_mac_address(packet->chaddr, iface_name) < 0) + exit(1); + + packet->magic[0]=0x63; + packet->magic[1]=0x82; + packet->magic[2]=0x53; + packet->magic[3]=0x63; + + packet->opt[0]=53; + packet->opt[1]=1; + packet->opt[2]=1; + + packet->opt[MAX_DHCP_OPTIONS_LENGTH - 1] = 0xFF; + + return 0; +} + +static int handle_dhcp_option(uint8_t option_type, const uint8_t* option_start, uint32_t option_length) +{ + //printf("Option type: %d (length: %d)\n", option_type, option_length); + + // http://networksorcery.com/enp/protocol/bootp/options.htm + switch(option_type) + { + case 1: //mask + { + printf("Mask: %u.%u.%u.%u\n", option_start[0], option_start[1], option_start[2], option_start[3]); + break; + } + case 6: //dns + { + printf("DNS Server: %u.%u.%u.%u\n", option_start[0], option_start[1], option_start[2], option_start[3]); + break; + } + case 15: //domain name + { + char domain_name[option_length + 1]; + strncpy(domain_name, (const char*)option_start, option_length); + domain_name[option_length] = '\0'; + printf("Domain name: %s\n", domain_name); + break; + } + case 54: //router + { + printf("DHCP server ip: %u.%u.%u.%u\n", option_start[0], option_start[1], option_start[2], option_start[3]); + break; + } + default: //undefined + return 0; //-1 + } + + return 0; +} + +static void print_dhcp_offer_info(const dhcp_packet_t* dhcp_offer) +{ + //uint32_t ip = ntohl(dhcp_offer->yiaddr); + //printf("Got IP %u.%u.%u.%u\n", ip >> 24, ((ip << 8) >> 24), (ip << 16) >> 24, (ip << 24) >> 24); + + size_t i = 0; + while(i < MAX_DHCP_OPTIONS_LENGTH && dhcp_offer->opt[i] != 0) + { + uint8_t option = dhcp_offer->opt[i++]; + uint32_t length = dhcp_offer->opt[i++]; + + if(handle_dhcp_option(option, &dhcp_offer->opt[i], length) < 0) + exit(1); + + i += dhcp_offer->opt[length]; + } +} + +int main(int argc, char** argv) +{ + const char* iface_name = NULL; + + char c; + while((c = getopt(argc, argv, "i:")) > 0) + { + switch(c) + { + case 'i': + iface_name = optarg; + break; + default: + usage: + printf("Usage: ./dhcpprobe -i %%INTERFACE\n"); + exit(1); + } + } + + if(iface_name == NULL) + goto usage; + + int sock_fd; + + printf("Creating socket...\n"); + if((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + exit(1); + else + printf("Succesfully created socket.\n"); + + printf("Setting socket options...\n"); + int broadcast_enabled = 1; + if(setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, &broadcast_enabled, sizeof(int)) < 0) + exit(1); + else + printf("Succesfully set socket options.\n"); + + printf("Binding... "); + struct sockaddr_in server_send_addr = {0}; + server_send_addr.sin_family = AF_INET; + server_send_addr.sin_addr.s_addr = inet_addr(BROADCAST_ADDRESS); + server_send_addr.sin_port = htons(67); + if(bind(sock_fd, (struct sockaddr*)&server_send_addr, sizeof(struct sockaddr_in)) < 0) + exit(1); + else + printf("Succesfully binded.\n"); + + printf("Sending dhcpdiscover...\n"); + dhcp_packet_t dhcp_discover = {0}; + construct_dhcp_discover(&dhcp_discover, iface_name); + + if(sendto(sock_fd, &dhcp_discover, sizeof(dhcp_packet_t), 0, (struct sockaddr*)&server_send_addr, sizeof(struct sockaddr_in)) == -1) + exit(1); + else + printf("Succesfully sent dhcpdiscover.\n"); + + close(sock_fd); + + if((sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + exit(1); + else + printf("Opened socket to recieve response.\n"); + + if(setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, &broadcast_enabled, sizeof(int)) < 0) + exit(1); + else + printf("Succesfully set socket options.\n"); + + struct sockaddr_in server_recv_addr = {0}; + server_recv_addr.sin_family = AF_INET; + server_recv_addr.sin_port = htons(68); + server_recv_addr.sin_addr.s_addr = INADDR_ANY; + + if(bind(sock_fd, (struct sockaddr*)&server_recv_addr, sizeof(struct sockaddr_in)) < 0) + exit(1); + else + printf("Succesfully binded.\n"); + + dhcp_packet_t dhcp_recv = {0}; + recieve: + if(recvfrom(sock_fd, &dhcp_recv, sizeof(dhcp_packet_t), 0, NULL, 0) < 0) + exit(1); + else if(dhcp_discover.xid != dhcp_recv.xid) + { + printf("Recieved invalid dhcp offer.\n"); + goto recieve; + } + else + printf("Succesfully recieved dhcp offer.\n"); + + print_dhcp_offer_info(&dhcp_recv); +} diff --git a/dhcp_probe.cflags b/dhcp_probe.cflags new file mode 100644 index 0000000..68d5165 --- /dev/null +++ b/dhcp_probe.cflags @@ -0,0 +1 @@ +-std=c17 \ No newline at end of file diff --git a/dhcp_probe.config b/dhcp_probe.config new file mode 100644 index 0000000..e0284f4 --- /dev/null +++ b/dhcp_probe.config @@ -0,0 +1,2 @@ +// Add predefined macros for your project here. For example: +// #define THE_ANSWER 42 diff --git a/dhcp_probe.creator b/dhcp_probe.creator new file mode 100644 index 0000000..e94cbbd --- /dev/null +++ b/dhcp_probe.creator @@ -0,0 +1 @@ +[General] diff --git a/dhcp_probe.creator.user b/dhcp_probe.creator.user new file mode 100644 index 0000000..916aafa --- /dev/null +++ b/dhcp_probe.creator.user @@ -0,0 +1,227 @@ + + + + + + EnvironmentId + {e4a6d94c-61a3-42c8-a0d7-27ab927ca53a} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + *.md, *.MD, Makefile + false + true + + + + ProjectExplorer.Project.PluginSettings + + + true + true + true + true + true + + + 0 + true + + true + Builtin.Questionable + + true + true + Builtin.DefaultTidyAndClazy + 4 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Desktop + {940da921-a368-46d8-94a2-042c01365756} + 0 + 0 + 0 + + /home/baitinq/dhcp_probe + + + + all + + true + GenericProjectManager.GenericMakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + GenericProjectManager.GenericMakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Default + GenericProjectManager.GenericBuildConfiguration + + 1 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 2 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/dhcp_probe.cxxflags b/dhcp_probe.cxxflags new file mode 100644 index 0000000..6435dfc --- /dev/null +++ b/dhcp_probe.cxxflags @@ -0,0 +1 @@ +-std=c++17 \ No newline at end of file diff --git a/dhcp_probe.files b/dhcp_probe.files new file mode 100644 index 0000000..ce24291 --- /dev/null +++ b/dhcp_probe.files @@ -0,0 +1 @@ +dhcp_probe.c diff --git a/dhcp_probe.includes b/dhcp_probe.includes new file mode 100644 index 0000000..e69de29 -- cgit 1.4.1