|  | @@ -130,6 +130,29 @@ static inline const char * dhcp_msgtype_name ( unsigned int msgtype ) {
 | 
		
	
		
			
			| 130 | 130 |  	}
 | 
		
	
		
			
			| 131 | 131 |  }
 | 
		
	
		
			
			| 132 | 132 |  
 | 
		
	
		
			
			|  | 133 | +/**
 | 
		
	
		
			
			|  | 134 | + * Transcribe DHCP client hardware address (for debugging)
 | 
		
	
		
			
			|  | 135 | + *
 | 
		
	
		
			
			|  | 136 | + * @v chaddr		Client hardware address
 | 
		
	
		
			
			|  | 137 | + * @v hlen		Client hardware address length
 | 
		
	
		
			
			|  | 138 | + */
 | 
		
	
		
			
			|  | 139 | +static const char * dhcp_chaddr_ntoa ( const void *chaddr, size_t hlen ) {
 | 
		
	
		
			
			|  | 140 | +	static char buf[ 48 /* 16 x ( "xx" + ":" or NUL ) */ ];
 | 
		
	
		
			
			|  | 141 | +	const uint8_t *chaddr_bytes = chaddr;
 | 
		
	
		
			
			|  | 142 | +	char *tmp = buf;
 | 
		
	
		
			
			|  | 143 | +
 | 
		
	
		
			
			|  | 144 | +	/* Sanity check */
 | 
		
	
		
			
			|  | 145 | +	assert ( hlen < ( sizeof ( buf ) / 3 ) );
 | 
		
	
		
			
			|  | 146 | +
 | 
		
	
		
			
			|  | 147 | +	/* Transcribe address */
 | 
		
	
		
			
			|  | 148 | +	while ( hlen-- ) {
 | 
		
	
		
			
			|  | 149 | +		tmp += sprintf ( tmp, "%s%02x", ( ( tmp == buf ) ? "" : ":" ),
 | 
		
	
		
			
			|  | 150 | +				 *(chaddr_bytes++) );
 | 
		
	
		
			
			|  | 151 | +	}
 | 
		
	
		
			
			|  | 152 | +
 | 
		
	
		
			
			|  | 153 | +	return buf;
 | 
		
	
		
			
			|  | 154 | +}
 | 
		
	
		
			
			|  | 155 | +
 | 
		
	
		
			
			| 133 | 156 |  /****************************************************************************
 | 
		
	
		
			
			| 134 | 157 |   *
 | 
		
	
		
			
			| 135 | 158 |   * DHCP session
 | 
		
	
	
		
			
			|  | @@ -1159,6 +1182,8 @@ static int dhcp_deliver ( struct dhcp_session *dhcp,
 | 
		
	
		
			
			| 1159 | 1182 |  	struct dhcphdr *dhcphdr;
 | 
		
	
		
			
			| 1160 | 1183 |  	uint8_t msgtype = 0;
 | 
		
	
		
			
			| 1161 | 1184 |  	struct in_addr server_id = { 0 };
 | 
		
	
		
			
			|  | 1185 | +	uint8_t chaddr[ sizeof ( dhcphdr->chaddr ) ];
 | 
		
	
		
			
			|  | 1186 | +	unsigned int hlen;
 | 
		
	
		
			
			| 1162 | 1187 |  	int rc = 0;
 | 
		
	
		
			
			| 1163 | 1188 |  
 | 
		
	
		
			
			| 1164 | 1189 |  	/* Sanity checks */
 | 
		
	
	
		
			
			|  | @@ -1203,9 +1228,21 @@ static int dhcp_deliver ( struct dhcp_session *dhcp,
 | 
		
	
		
			
			| 1203 | 1228 |  		goto err_xid;
 | 
		
	
		
			
			| 1204 | 1229 |  	};
 | 
		
	
		
			
			| 1205 | 1230 |  
 | 
		
	
		
			
			|  | 1231 | +	/* Check for matching client hardware address */
 | 
		
	
		
			
			|  | 1232 | +	hlen = dhcp_chaddr ( dhcp->netdev, chaddr, NULL );
 | 
		
	
		
			
			|  | 1233 | +	if ( memcmp ( dhcphdr->chaddr, chaddr, hlen ) != 0 ) {
 | 
		
	
		
			
			|  | 1234 | +		DBGC ( dhcp, "DHCP %p %s from %s:%d has bad chaddr %s\n",
 | 
		
	
		
			
			|  | 1235 | +		       dhcp, dhcp_msgtype_name ( msgtype ),
 | 
		
	
		
			
			|  | 1236 | +		       inet_ntoa ( peer->sin_addr ), ntohs ( peer->sin_port ),
 | 
		
	
		
			
			|  | 1237 | +		       dhcp_chaddr_ntoa ( dhcphdr->chaddr, hlen ) );
 | 
		
	
		
			
			|  | 1238 | +		rc = -EINVAL;
 | 
		
	
		
			
			|  | 1239 | +		goto err_chaddr;
 | 
		
	
		
			
			|  | 1240 | +	}
 | 
		
	
		
			
			|  | 1241 | +
 | 
		
	
		
			
			| 1206 | 1242 |  	/* Handle packet based on current state */
 | 
		
	
		
			
			| 1207 | 1243 |  	dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype, server_id );
 | 
		
	
		
			
			| 1208 | 1244 |  
 | 
		
	
		
			
			|  | 1245 | + err_chaddr:
 | 
		
	
		
			
			| 1209 | 1246 |   err_xid:
 | 
		
	
		
			
			| 1210 | 1247 |  	dhcppkt_put ( dhcppkt );
 | 
		
	
		
			
			| 1211 | 1248 |   err_alloc_dhcppkt:
 |