mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
netd: implement client id and hostname options for DHCPDISCOVER
This commit is contained in:
+48
-3
@@ -1,3 +1,4 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#ifndef SIOCADDRT
|
#ifndef SIOCADDRT
|
||||||
#define SIOCADDRT 0x890B
|
#define SIOCADDRT 0x890B
|
||||||
@@ -61,6 +63,12 @@ typedef struct {
|
|||||||
#define OPTION_REQUEST 55
|
#define OPTION_REQUEST 55
|
||||||
#define OPTION_REQUEST_LENGTH 3
|
#define OPTION_REQUEST_LENGTH 3
|
||||||
|
|
||||||
|
#define OPTION_CLIENT_ID 61
|
||||||
|
#define OPTION_CLIENT_ID_LENGTH 7
|
||||||
|
|
||||||
|
#define OPTION_HOSTNAME 12
|
||||||
|
#define OPTION_HOSTNAME_LENGTH 64
|
||||||
|
|
||||||
#define OPTION_MASK 1
|
#define OPTION_MASK 1
|
||||||
#define OPTION_ROUTER 3
|
#define OPTION_ROUTER 3
|
||||||
#define OPTION_DNS 6
|
#define OPTION_DNS 6
|
||||||
@@ -69,16 +77,23 @@ typedef struct {
|
|||||||
#define OPTION_SERVER 54
|
#define OPTION_SERVER 54
|
||||||
#define OPTION_END 0xff
|
#define OPTION_END 0xff
|
||||||
|
|
||||||
|
#define DISCOVEROPTS_OFFSET_CLIENT_ID 11
|
||||||
|
#define DISCOVEROPTS_OFFSET_HOSTNAME 19
|
||||||
|
|
||||||
static uint8_t discoveropts[] = {
|
static uint8_t discoveropts[] = {
|
||||||
OPTION_TYPE, OPTION_TYPE_LENGTH, OPTION_TYPE_DHCPDISCOVER,
|
OPTION_TYPE, OPTION_TYPE_LENGTH, OPTION_TYPE_DHCPDISCOVER,
|
||||||
OPTION_REQUEST, OPTION_REQUEST_LENGTH, OPTION_MASK, OPTION_ROUTER, OPTION_DNS,
|
OPTION_REQUEST, OPTION_REQUEST_LENGTH, OPTION_MASK, OPTION_ROUTER, OPTION_DNS,
|
||||||
0xff
|
OPTION_CLIENT_ID, OPTION_CLIENT_ID_LENGTH, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
OPTION_HOSTNAME, OPTION_HOSTNAME_LENGTH,
|
||||||
|
// 64 bytes for hostname
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
OPTION_END
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
dhcphdr_t hdr;
|
dhcphdr_t hdr;
|
||||||
uint8_t opts[sizeof(discoveropts)];
|
uint8_t opts[sizeof(discoveropts)];
|
||||||
uint8_t padding[300 - sizeof(dhcphdr_t) - sizeof(discoveropts)];
|
|
||||||
} __attribute__((packed)) dhcpdiscover_t;
|
} __attribute__((packed)) dhcpdiscover_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -92,13 +107,19 @@ typedef struct {
|
|||||||
uint32_t ipreq;
|
uint32_t ipreq;
|
||||||
uint8_t dhcpserverhdr[2];
|
uint8_t dhcpserverhdr[2];
|
||||||
uint32_t dhcpserver;
|
uint32_t dhcpserver;
|
||||||
|
uint8_t userid;
|
||||||
|
uint8_t useridlen;
|
||||||
|
uint8_t useridtype;
|
||||||
|
uint8_t useridhwaddr[6];
|
||||||
|
uint8_t hn;
|
||||||
|
uint8_t hnlen;
|
||||||
|
uint8_t hndata[64];
|
||||||
uint8_t end;
|
uint8_t end;
|
||||||
} __attribute__((packed)) requestopts_t;
|
} __attribute__((packed)) requestopts_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
dhcphdr_t hdr;
|
dhcphdr_t hdr;
|
||||||
requestopts_t opts;
|
requestopts_t opts;
|
||||||
uint8_t padding[300 - sizeof(dhcphdr_t) - sizeof(requestopts_t)];
|
|
||||||
} __attribute__((packed)) dhcprequest_t;
|
} __attribute__((packed)) dhcprequest_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -323,6 +344,13 @@ static int request(offer_t *offer) {
|
|||||||
packet.opts.dhcpserverhdr[0] = OPTION_SERVER;
|
packet.opts.dhcpserverhdr[0] = OPTION_SERVER;
|
||||||
packet.opts.dhcpserverhdr[1] = 4;
|
packet.opts.dhcpserverhdr[1] = 4;
|
||||||
packet.opts.dhcpserver = htonl(offer->serverip);
|
packet.opts.dhcpserver = htonl(offer->serverip);
|
||||||
|
packet.opts.userid = OPTION_CLIENT_ID;
|
||||||
|
packet.opts.useridlen = OPTION_CLIENT_ID_LENGTH;
|
||||||
|
packet.opts.useridtype = 1;
|
||||||
|
memcpy(packet.opts.useridhwaddr, hwaddr, 6);
|
||||||
|
packet.opts.hn = OPTION_HOSTNAME;
|
||||||
|
gethostname(packet.opts.hndata, 64);
|
||||||
|
packet.opts.hnlen = packet.opts.hndata[63] ? 64 : strlen(packet.opts.hndata);
|
||||||
packet.opts.end = 0xff;
|
packet.opts.end = 0xff;
|
||||||
|
|
||||||
// broadcast address
|
// broadcast address
|
||||||
@@ -475,48 +503,65 @@ int main(int argc, char *argv[]) {
|
|||||||
xid = ((uint32_t)rand() << 16) ^ (uint32_t)rand();
|
xid = ((uint32_t)rand() << 16) ^ (uint32_t)rand();
|
||||||
discoverstart = time(NULL);
|
discoverstart = time(NULL);
|
||||||
|
|
||||||
|
memcpy(&discoveropts[DISCOVEROPTS_OFFSET_CLIENT_ID], hwaddr, 6);
|
||||||
|
gethostname(&discoveropts[DISCOVEROPTS_OFFSET_HOSTNAME], 64);
|
||||||
|
if (discoveropts[DISCOVEROPTS_OFFSET_HOSTNAME + 63] == '\0')
|
||||||
|
discoveropts[DISCOVEROPTS_OFFSET_HOSTNAME - 1] = strlen(&discoveropts[DISCOVEROPTS_OFFSET_HOSTNAME]);
|
||||||
|
|
||||||
offer_t offer;
|
offer_t offer;
|
||||||
|
|
||||||
bool gotoffer = false;
|
bool gotoffer = false;
|
||||||
|
|
||||||
while (gotoffer == false) {
|
while (gotoffer == false) {
|
||||||
|
printf("sending discover...\n");
|
||||||
if (discover())
|
if (discover())
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
printf("waiting for offer...\n");
|
||||||
while (gotoffer == false) {
|
while (gotoffer == false) {
|
||||||
if (waitforserver(10000))
|
if (waitforserver(10000))
|
||||||
break;
|
break;
|
||||||
|
printf("got offer!\n");
|
||||||
|
|
||||||
uint32_t rxid;
|
uint32_t rxid;
|
||||||
|
|
||||||
if (processoffer(&offer, &rxid))
|
if (processoffer(&offer, &rxid))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
printf("processed offer!\n");
|
||||||
|
|
||||||
// packet wasn't for this machine
|
// packet wasn't for this machine
|
||||||
if (rxid != xid)
|
if (rxid != xid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
printf("packet id ok\n");
|
||||||
|
|
||||||
gotoffer = true;
|
gotoffer = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gotack = false;
|
bool gotack = false;
|
||||||
while (gotack == false) {
|
while (gotack == false) {
|
||||||
|
printf("sending request...\n");
|
||||||
if (request(&offer))
|
if (request(&offer))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
printf("waiting for ack...\n");
|
||||||
while (gotack == false) {
|
while (gotack == false) {
|
||||||
if (waitforserver(10000))
|
if (waitforserver(10000))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
uint32_t rxid;
|
uint32_t rxid;
|
||||||
|
|
||||||
|
printf("got ack\n");
|
||||||
if (getack(&rxid))
|
if (getack(&rxid))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
printf("ack ok\n");
|
||||||
if (rxid != xid)
|
if (rxid != xid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
printf("ack id ok\n");
|
||||||
gotack = true;
|
gotack = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user