View | Details | Raw Unified
Collapse All | Expand All

(-)a/dhcp.c (+48 lines)
 Lines 25-30    Link Here 
25
 */
25
 */
26
26
27
27
28
#include <stdio.h>
28
#include <stdlib.h>
29
#include <stdlib.h>
29
#include <unistd.h>
30
#include <unistd.h>
30
#include <string.h>
31
#include <string.h>
 Lines 38-43    Link Here 
38
#include <net/ethernet.h>
39
#include <net/ethernet.h>
39
#include <netinet/ip.h>
40
#include <netinet/ip.h>
40
#include <netinet/udp.h>
41
#include <netinet/udp.h>
42
#include <sys/utsname.h>
41
#include <sys/time.h>
43
#include <sys/time.h>
42
#include <time.h>
44
#include <time.h>
43
#include <fcntl.h>
45
#include <fcntl.h>
 Lines 49-54    Link Here 
49
#include "frontend.h"
51
#include "frontend.h"
50
52
51
#include "dhcp.h"
53
#include "dhcp.h"
54
#include "version.h"
52
55
53
56
54
typedef int bp_int32;
57
typedef int bp_int32;
 Lines 68-73   typedef short bp_int16; Link Here 
68
#define DHCP_OPTION_SERVER		54
71
#define DHCP_OPTION_SERVER		54
69
#define DHCP_OPTION_OPTIONREQ	55
72
#define DHCP_OPTION_OPTIONREQ	55
70
#define DHCP_OPTION_MAXSIZE		57
73
#define DHCP_OPTION_MAXSIZE		57
74
#define DHCP_OPTION_VENDORCLASS	60
75
76
#define DHCP_VENDOR_CLASS_ID_PREFIX "ALT-Propagator"
71
77
72
#define BOOTP_CLIENT_PORT	68
78
#define BOOTP_CLIENT_PORT	68
73
#define BOOTP_SERVER_PORT	67
79
#define BOOTP_SERVER_PORT	67
 Lines 101-106   struct bootp_request { Link Here 
101
107
102
static const char vendor_cookie[] = { 99, 130, 83, 99, 255 };
108
static const char vendor_cookie[] = { 99, 130, 83, 99, 255 };
103
109
110
// This function's return value needs to be freed after use.
111
static char* get_vendor_class_id() {
112
	// mimicking dhcpcd
113
	char* ret;
114
	struct utsname u;
115
	unsigned int sz = sizeof(DHCP_VENDOR_CLASS_ID_PREFIX) +
116
		sizeof(VERSION);
117
	if (uname(&u) != 0) {
118
		if ((ret = malloc(sz)) == NULL) {
119
			log_perror("malloc");
120
			return ret;
121
		}
122
		sprintf(ret, "%s-%s", DHCP_VENDOR_CLASS_ID_PREFIX, VERSION);
123
	}
124
	else {
125
		sz += sizeof(DHCP_VENDOR_CLASS_ID_PREFIX) +
126
			strlen(u.sysname) + 1 +
127
			strlen(u.release) + 1 +
128
			strlen(u.machine) + 1;
129
		if ((ret = malloc(sz)) == NULL) {
130
			log_perror("malloc");
131
			return ret;
132
		}
133
		sprintf(ret, "%s-%s:%s-%s:%s", DHCP_VENDOR_CLASS_ID_PREFIX, VERSION,
134
				u.sysname, u.release, u.machine);
135
	}
136
    return ret;
137
}
104
138
105
static unsigned int verify_checksum(void * buf2, int length2)
139
static unsigned int verify_checksum(void * buf2, int length2)
106
{
140
{
 Lines 523-528   enum return_type perform_dhcp(struct interface_info * intf) Link Here 
523
	struct sockaddr_in broadcast_addr;
557
	struct sockaddr_in broadcast_addr;
524
	struct bootp_request breq, bresp;
558
	struct bootp_request breq, bresp;
525
	unsigned char messageType;
559
	unsigned char messageType;
560
	char* vendorClass;
526
	unsigned int lease;
561
	unsigned int lease;
527
	short aShort;
562
	short aShort;
528
	int num_options;
563
	int num_options;
 Lines 565-570   enum return_type perform_dhcp(struct interface_info * intf) Link Here 
565
	broadcast_addr.sin_port = htons(BOOTP_SERVER_PORT);	/* bootp server */
600
	broadcast_addr.sin_port = htons(BOOTP_SERVER_PORT);	/* bootp server */
566
	memset(&broadcast_addr.sin_addr, 0xff, sizeof(broadcast_addr.sin_addr));  /* broadcast */
601
	memset(&broadcast_addr.sin_addr, 0xff, sizeof(broadcast_addr.sin_addr));  /* broadcast */
567
602
603
	vendorClass = get_vendor_class_id();
604
	add_vendor_code(&breq, DHCP_OPTION_VENDORCLASS,
605
		strlen(vendorClass),
606
		vendorClass);
607
568
	log_message("DHCP: sending DISCOVER");
608
	log_message("DHCP: sending DISCOVER");
569
609
570
	wait_message("Sending DHCP request...");
610
	wait_message("Sending DHCP request...");
 Lines 574-579   enum return_type perform_dhcp(struct interface_info * intf) Link Here 
574
	if (i != 0) {
614
	if (i != 0) {
575
		stg1_info_message("No DHCP reply received.");
615
		stg1_info_message("No DHCP reply received.");
576
		close(s);
616
		close(s);
617
		free(vendorClass);
577
		return RETURN_ERROR;
618
		return RETURN_ERROR;
578
	}
619
	}
579
620
 Lines 582-593   enum return_type perform_dhcp(struct interface_info * intf) Link Here 
582
	if (get_vendor_code(&bresp, DHCP_OPTION_SERVER, &server_addr.sin_addr)) {
623
	if (get_vendor_code(&bresp, DHCP_OPTION_SERVER, &server_addr.sin_addr)) {
583
		close(s);
624
		close(s);
584
		log_message("DHCPOFFER didn't include server address");
625
		log_message("DHCPOFFER didn't include server address");
626
		free(vendorClass);
585
		return RETURN_ERROR;
627
		return RETURN_ERROR;
586
	}
628
	}
587
629
588
	init_vendor_codes(&breq);
630
	init_vendor_codes(&breq);
589
	messageType = DHCP_TYPE_REQUEST;
631
	messageType = DHCP_TYPE_REQUEST;
590
	add_vendor_code(&breq, DHCP_OPTION_TYPE, 1, &messageType);
632
	add_vendor_code(&breq, DHCP_OPTION_TYPE, 1, &messageType);
633
	add_vendor_code(&breq, DHCP_OPTION_VENDORCLASS,
634
		strlen(vendorClass),
635
		vendorClass);
591
	add_vendor_code(&breq, DHCP_OPTION_SERVER, 4, &server_addr.sin_addr);
636
	add_vendor_code(&breq, DHCP_OPTION_SERVER, 4, &server_addr.sin_addr);
592
	add_vendor_code(&breq, DHCP_OPTION_REQADDR, 4, &bresp.yiaddr);
637
	add_vendor_code(&breq, DHCP_OPTION_REQADDR, 4, &bresp.yiaddr);
593
638
 Lines 613-628   enum return_type perform_dhcp(struct interface_info * intf) Link Here 
613
658
614
	if (i != 0) {
659
	if (i != 0) {
615
		close(s);
660
		close(s);
661
		free(vendorClass);
616
		return RETURN_ERROR;
662
		return RETURN_ERROR;
617
	}
663
	}
618
664
619
	if (get_vendor_code(&bresp, DHCP_OPTION_LEASE, &lease)) {
665
	if (get_vendor_code(&bresp, DHCP_OPTION_LEASE, &lease)) {
620
		log_message("failed to get lease time\n");
666
		log_message("failed to get lease time\n");
667
		free(vendorClass);
621
		return RETURN_ERROR;
668
		return RETURN_ERROR;
622
	}
669
	}
623
	lease = ntohl(lease);
670
	lease = ntohl(lease);
624
671
625
	close(s);
672
	close(s);
673
	free(vendorClass);
626
674
627
	intf->netmask.s_addr = 0;
675
	intf->netmask.s_addr = 0;
628
	intf->broadcast.s_addr = 0;
676
	intf->broadcast.s_addr = 0;