aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/services/dnsmasq/patches/020-implement-RFC6842.patch
blob: 905e40b8ca3fe0dfff3726a62488ac6a25cc1ead (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
From 88a77a78ad27adc3ed87b7ee603643d26cb896ee Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Sat, 11 Feb 2017 17:02:02 +0000
Subject: [PATCH] Implement RFC-6842 (Client-ids in DHCP replies.)

---
 CHANGELOG     |    5 ++++-
 src/rfc2131.c |   33 ++++++++++++++++++++++-----------
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index f7f5125..a4ee280 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -74,7 +74,10 @@ version 2.77
 	    of "local addresses only" entries. Thanks to Hannu Nyman for
 	    the patch.
 
-	
+            Implement RFC 6842. Thanks to Reddeiah Raju Konduru for
+            pointing out that this was missing.
+
+
 version 2.76
             Include 0.0.0.0/8 in DNS rebind checks. This range 
 	    translates to hosts on  the local network, or, at 
diff --git a/src/rfc2131.c b/src/rfc2131.c
index 978c8dc..3e97402 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -38,7 +38,7 @@ static void log_packet(char *type, void *addr, unsigned char *ext_mac,
 static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
 static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
 static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id, unsigned char *real_end);
-static void clear_packet(struct dhcp_packet *mess, unsigned char *end);
+static void clear_packet(struct dhcp_packet *mess, unsigned char *end, unsigned int sz);
 static int in_list(unsigned char *list, int opt);
 static void do_options(struct dhcp_context *context,
 		       struct dhcp_packet *mess,
@@ -611,7 +611,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
 				now); 
 	      lease_set_interface(lease, int_index, now);
 	      
-	      clear_packet(mess, end);
+	      clear_packet(mess, end, 0);
 	      do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr), 
 			 netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now, 0xffffffff, 0);
 	    }
@@ -814,7 +814,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
 	  if (!service || !service->basename || !context)
 	    return 0;
 	  	  
-	  clear_packet(mess, end);
+	  clear_packet(mess, end, sz);
 	  
 	  mess->yiaddr = mess->ciaddr;
 	  mess->ciaddr.s_addr = 0;
@@ -882,7 +882,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
 		      mess->flags |= htons(0x8000); /* broadcast */
 		    }
 		  
-		  clear_packet(mess, end);
+		  clear_packet(mess, end, sz);
 		  
 		  /* Redirect EFI clients to port 4011 */
 		  if (pxearch >= 6)
@@ -1062,7 +1062,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
       log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
       
       time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
-      clear_packet(mess, end);
+      clear_packet(mess, end, sz);
       option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPOFFER);
       option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
       option_put(mess, end, OPTION_LEASE_TIME, 4, time);
@@ -1245,7 +1245,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
 	  log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
 	  
 	  mess->yiaddr.s_addr = 0;
-	  clear_packet(mess, end);
+	  clear_packet(mess, end, sz);
 	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
 	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
 	  option_put_string(mess, end, OPTION_MESSAGE, message, borken_opt);
@@ -1401,7 +1401,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
 
 	  log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);  
 	  
-	  clear_packet(mess, end);
+	  clear_packet(mess, end, sz);
 	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
 	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
 	  option_put(mess, end, OPTION_LEASE_TIME, 4, time);
@@ -1452,7 +1452,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
 	    override = lease->override;
 	}
 
-      clear_packet(mess, end);
+      clear_packet(mess, end, sz);
       option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
       option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
      
@@ -2180,12 +2180,23 @@ static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct
  
   return ret;
 }
-  
-static void clear_packet(struct dhcp_packet *mess, unsigned char *end)
+
+static void clear_packet(struct dhcp_packet *mess, unsigned char *end, unsigned int sz)
 {
+  unsigned char *opt;
+  unsigned int clid_tot = 0;
+  
+  /* If sz is non-zero, save any client-id option by copying it as the first
+   option in the new packet */
+    if (sz != 0 && (opt = option_find(mess, sz, OPTION_CLIENT_ID, 1)))
+    {
+      clid_tot = option_len(opt) + 2u;
+      memmove(&mess->options[0] + sizeof(u32), opt, clid_tot);
+    }
+  
   memset(mess->sname, 0, sizeof(mess->sname));
   memset(mess->file, 0, sizeof(mess->file));
-  memset(&mess->options[0] + sizeof(u32), 0, end - (&mess->options[0] + sizeof(u32)));
+  memset(&mess->options[0] + sizeof(u32) + clid_tot, 0, end - (&mess->options[0] + sizeof(u32) + clid_tot));
   mess->siaddr.s_addr = 0;
 }
 
-- 
1.7.10.4