diff --git a/dhcp.c b/dhcp.c index 78a81a2..a543dc7 100644 --- a/dhcp.c +++ b/dhcp.c @@ -25,6 +25,7 @@ */ +#include #include #include #include @@ -38,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +51,7 @@ #include "frontend.h" #include "dhcp.h" +#include "version.h" typedef int bp_int32; @@ -68,6 +71,9 @@ typedef short bp_int16; #define DHCP_OPTION_SERVER 54 #define DHCP_OPTION_OPTIONREQ 55 #define DHCP_OPTION_MAXSIZE 57 +#define DHCP_OPTION_VENDORCLASS 60 + +#define DHCP_VENDOR_CLASS_ID_PREFIX "ALT-Propagator" #define BOOTP_CLIENT_PORT 68 #define BOOTP_SERVER_PORT 67 @@ -101,6 +107,25 @@ struct bootp_request { static const char vendor_cookie[] = { 99, 130, 83, 99, 255 }; +static char vendor_class_id[ + sizeof(DHCP_VENDOR_CLASS_ID_PREFIX) + + sizeof(VERSION) + + sizeof(((struct utsname*)0)->sysname) + 1 + + sizeof(((struct utsname*)0)->release) + 1 + + sizeof(((struct utsname*)0)->machine) + 1 +] = { 0 }; + +static void make_vendor_class_id(void) { + struct utsname u; + + uname(&u); + + /* mimicking dhcpcd */ + snprintf(vendor_class_id, sizeof(vendor_class_id), + "%s-%s:%s-%s:%s", + DHCP_VENDOR_CLASS_ID_PREFIX, VERSION, + u.sysname, u.release, u.machine); +} static unsigned int verify_checksum(void * buf2, int length2) { @@ -535,6 +560,8 @@ enum return_type perform_dhcp(struct interface_info * intf) } */ + make_vendor_class_id(); + s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { log_perror("socket"); @@ -567,6 +594,10 @@ enum return_type perform_dhcp(struct interface_info * intf) broadcast_addr.sin_port = htons(BOOTP_SERVER_PORT); /* bootp server */ memset(&broadcast_addr.sin_addr, 0xff, sizeof(broadcast_addr.sin_addr)); /* broadcast */ + add_vendor_code(&breq, DHCP_OPTION_VENDORCLASS, + strlen(vendor_class_id), + vendor_class_id); + log_message("DHCP: sending DISCOVER"); wait_message("Sending DHCP request..."); @@ -593,6 +624,10 @@ enum return_type perform_dhcp(struct interface_info * intf) add_vendor_code(&breq, DHCP_OPTION_SERVER, 4, &server_addr.sin_addr); add_vendor_code(&breq, DHCP_OPTION_REQADDR, 4, &bresp.yiaddr); + add_vendor_code(&breq, DHCP_OPTION_VENDORCLASS, + strlen(vendor_class_id), + vendor_class_id); + aShort = ntohs(sizeof(struct bootp_request)); add_vendor_code(&breq, DHCP_OPTION_MAXSIZE, 2, &aShort);