Re: [systemd-devel] [PATCH] sd-dhcp-client: support non-Ethernet hardware addresses

2014-10-06 Thread Patrik Flykt
On Fri, 2014-10-03 at 10:04 -0500, Dan Williams wrote:
 sd_dhcp_client_set_mac() does have an 'arp_type' parameter that's
 cached
 in the client struct, so that could be changed to:
 
 if (client-arp_type == ARPHRD_ETHER)
 
 if you'd like.

If it's there already, it is a good thing to use. It does look clearer
in the code that way.

Thanks,

Patrik


___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] sd-dhcp-client: support non-Ethernet hardware addresses

2014-10-03 Thread Patrik Flykt

Hi,

On Thu, 2014-10-02 at 20:05 +0200, Tom Gundersen wrote:
  The DHCPv4 header is the same format no matter what the LL address size,
  but for non-ethernet the hlen is 0 and the chaddr is zeroed.  The BPF is
  seeded with an hlen of 0 and a valid ETH_ALEN sized buffer of all zeros.
  So both the hlen and chaddr comparisons comparison should succeed.
 
  Does that make sense?  I might have missed something too though...
 
 So that sounds fine, but my concern was: are we guaranteed that all
 implementations properly zero out the remaining bytes past the hlen
 first ones? Sounds weird to reject a package if it has hlen == 0 and
 garbage in chaddr, or is the zeroing something we can rely on? (In
 that case I guess we should extend the check to check all 16 bytes,
 and not only the 6 first ones to make it truly agnostic).
 
 Patrik, any thoughts?

At least RFC2131 says that the DHCP server uses the 'chaddr' supplied by
the client without considering hardware address length in 'hlen'.
Apparently both client and server need to use the same hardware
addressing, so 'hlen' on both ends match anyway.

Since our client implementation has properly zeroed out the DHCP header
before filling it with information, there should be no problem just
comparing all 16 bytes of 'chaddr' where the first 'hlen' bytes is the
hardware address and the rest should definitely be zero, since that was
what was sent in the first place. Currently the client side
implementation only checks that the N first bytes containing the MAC
address, so technically that is a bug. For a hardware address length of
zero, 'chaddr' should match what the client sent, in our case 16 bytes
of zeroes.


Cheers,

Patrik

___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] sd-dhcp-client: support non-Ethernet hardware addresses

2014-10-03 Thread Patrik Flykt
On Fri, 2014-10-03 at 15:48 +0300, Patrik Flykt wrote:
 On Fri, 2014-09-26 at 15:15 -0500, Dan Williams wrote:
   /* RFC2132 section 4.1.1:
  The client MUST include its hardware address in the ’chaddr’ 
  field, if
  -   necessary for delivery of DHCP reply messages.
  +   necessary for delivery of DHCP reply messages.  Non-Ethernet
  +   interfaces will leave 'chaddr' empty and use the client 
  identifier
  +   instead (eg, RFC 4390 section 2.1).
*/
  -memcpy(packet-dhcp.chaddr, client-client_id.mac_addr, 
  ETH_ALEN);
  +if (client-mac_addr_len == ETH_ALEN)
  +memcpy(packet-dhcp.chaddr, client-mac_addr, ETH_ALEN);
 
 Sorry about the late review, but shouldn't this be more generic if
 written:
 if (client-mac_addr_len)
 memcpy(packet-dhcp.chaddr, client-mac_addr, 
 client-mac_addr_len);
 
 With that, all cases are covered. Which, AFAIK, are none in addition to
 ethernet. An assert() should check the given MAC address length at some
 point in the code so that it cannot be  16.

And then I notice that infiniband has a MAC address length of 20. For
all practical purposes this works as expected. Except if we want to go
nitpicking when setting the MAC address and also require the address
type to be supplied? Probably not...

Cheers,

Patrik


___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] sd-dhcp-client: support non-Ethernet hardware addresses

2014-10-03 Thread Dan Williams
On Fri, 2014-10-03 at 16:10 +0300, Patrik Flykt wrote:
 On Fri, 2014-10-03 at 15:48 +0300, Patrik Flykt wrote:
  On Fri, 2014-09-26 at 15:15 -0500, Dan Williams wrote:
/* RFC2132 section 4.1.1:
   The client MUST include its hardware address in the ’chaddr’ 
   field, if
   -   necessary for delivery of DHCP reply messages.
   +   necessary for delivery of DHCP reply messages.  Non-Ethernet
   +   interfaces will leave 'chaddr' empty and use the client 
   identifier
   +   instead (eg, RFC 4390 section 2.1).
 */
   -memcpy(packet-dhcp.chaddr, client-client_id.mac_addr, 
   ETH_ALEN);
   +if (client-mac_addr_len == ETH_ALEN)
   +memcpy(packet-dhcp.chaddr, client-mac_addr, 
   ETH_ALEN);
  
  Sorry about the late review, but shouldn't this be more generic if
  written:
  if (client-mac_addr_len)
  memcpy(packet-dhcp.chaddr, client-mac_addr, 
  client-mac_addr_len);
  
  With that, all cases are covered. Which, AFAIK, are none in addition to
  ethernet. An assert() should check the given MAC address length at some
  point in the code so that it cannot be  16.
 
 And then I notice that infiniband has a MAC address length of 20. For
 all practical purposes this works as expected. Except if we want to go
 nitpicking when setting the MAC address and also require the address
 type to be supplied? Probably not...

sd_dhcp_client_set_mac() does have an 'arp_type' parameter that's cached
in the client struct, so that could be changed to:

if (client-arp_type == ARPHRD_ETHER)

if you'd like.

Dan


___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] [PATCH] sd-dhcp-client: support non-Ethernet hardware addresses

2014-10-02 Thread Tom Gundersen
On Fri, Sep 26, 2014 at 10:15 PM, Dan Williams d...@redhat.com wrote:
 Like Infiniband.  See RFC 4390 section 2.1 for details on DHCP
 and Infiniband; chaddr is zeroed, hlen is set to 0, and htype
 is set to ARPHRD_INFINIBAND because IB hardware addresses
 are 20 bytes in length.

Sorry for taking time with this. Overall looks good, just minor comments inline.

 ---
  src/libsystemd-network/dhcp-internal.h| 10 +++--
  src/libsystemd-network/dhcp-network.c | 54 -
  src/libsystemd-network/dhcp-packet.c  |  8 ++--
  src/libsystemd-network/sd-dhcp-client.c   | 66 
 +++
  src/libsystemd-network/sd-dhcp-server.c   |  8 ++--
  src/libsystemd-network/test-dhcp-client.c | 14 +--
  src/libsystemd-network/test-dhcp-option.c |  2 +-
  src/network/networkd-dhcp4.c  |  4 +-
  src/network/networkd-link.c   |  4 +-
  src/systemd/sd-dhcp-client.h  |  4 +-
  10 files changed, 130 insertions(+), 44 deletions(-)

 *** Testing appreciated

 diff --git a/src/libsystemd-network/dhcp-internal.h 
 b/src/libsystemd-network/dhcp-internal.h
 index 1069c8a..d358a49 100644
 --- a/src/libsystemd-network/dhcp-internal.h
 +++ b/src/libsystemd-network/dhcp-internal.h
 @@ -20,22 +20,25 @@

You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see http://www.gnu.org/licenses/.
  ***/

  #include stdint.h
  #include linux/if_packet.h
 +#include net/if_arp.h
  #include net/ethernet.h

  #include socket-util.h

  #include sd-dhcp-client.h
  #include dhcp-protocol.h

 -int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, 
 uint32_t xid, struct ether_addr mac_addr);
 +int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
 + uint32_t xid, const uint8_t *mac_addr,
 + size_t mac_addr_len, uint16_t arp_type);
  int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
  int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
   const void *packet, size_t len);
  int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
   const void *packet, size_t len);

  int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, 
 uint8_t overload,
 @@ -43,16 +46,17 @@ int dhcp_option_append(DHCPMessage *message, size_t size, 
 size_t *offset, uint8_

  typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len,
  const uint8_t *option, void *user_data);

  int dhcp_option_parse(DHCPMessage *message, size_t len,
dhcp_option_cb_t cb, void *user_data);

 -int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, 
 uint8_t type,
 -  size_t optlen, size_t *optoffset);
 +int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
 +  uint8_t type, uint16_t arp_type, size_t optlen,
 +  size_t *optoffset);

  uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len);

  void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
 uint16_t source, be32_t destination_addr,
 uint16_t destination, uint16_t len);

 diff --git a/src/libsystemd-network/dhcp-network.c 
 b/src/libsystemd-network/dhcp-network.c
 index 1ced5cf..29e9993 100644
 --- a/src/libsystemd-network/dhcp-network.c
 +++ b/src/libsystemd-network/dhcp-network.c
 @@ -18,27 +18,31 @@
  ***/

  #include errno.h
  #include sys/types.h
  #include sys/socket.h
  #include string.h
  #include linux/if_packet.h
 +#include linux/if_infiniband.h
  #include net/ethernet.h
  #include net/if_arp.h
  #include stdio.h
  #include unistd.h
  #include linux/filter.h

  #include socket-util.h

  #include dhcp-internal.h

 -int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
 - uint32_t xid, struct ether_addr mac_addr) {
 -
 +static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
 +uint32_t xid, const uint8_t *mac_addr,
 +size_t mac_addr_len,
 +const uint8_t *bcast_addr,
 +const struct ether_addr *eth_mac,
 +uint16_t arp_type, uint8_t dhcp_hlen) {
  struct sock_filter filter[] = {
  BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),   
   /* A - packet length */
  BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 
 0), /* packet = DHCPPacket ? */
  BPF_STMT(BPF_RET + BPF_K, 0),
   /* ignore */
  BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, 
 ip.protocol)), /* A - IP protocol */
  

Re: [systemd-devel] [PATCH] sd-dhcp-client: support non-Ethernet hardware addresses

2014-10-02 Thread Dan Williams
On Thu, 2014-10-02 at 16:39 +0200, Tom Gundersen wrote:
 On Fri, Sep 26, 2014 at 10:15 PM, Dan Williams d...@redhat.com wrote:
  Like Infiniband.  See RFC 4390 section 2.1 for details on DHCP
  and Infiniband; chaddr is zeroed, hlen is set to 0, and htype
  is set to ARPHRD_INFINIBAND because IB hardware addresses
  are 20 bytes in length.
 
 Sorry for taking time with this. Overall looks good, just minor comments 
 inline.
 
  ---
   src/libsystemd-network/dhcp-internal.h| 10 +++--
   src/libsystemd-network/dhcp-network.c | 54 -
   src/libsystemd-network/dhcp-packet.c  |  8 ++--
   src/libsystemd-network/sd-dhcp-client.c   | 66 
  +++
   src/libsystemd-network/sd-dhcp-server.c   |  8 ++--
   src/libsystemd-network/test-dhcp-client.c | 14 +--
   src/libsystemd-network/test-dhcp-option.c |  2 +-
   src/network/networkd-dhcp4.c  |  4 +-
   src/network/networkd-link.c   |  4 +-
   src/systemd/sd-dhcp-client.h  |  4 +-
   10 files changed, 130 insertions(+), 44 deletions(-)
 
  *** Testing appreciated
 
  diff --git a/src/libsystemd-network/dhcp-internal.h 
  b/src/libsystemd-network/dhcp-internal.h
  index 1069c8a..d358a49 100644
  --- a/src/libsystemd-network/dhcp-internal.h
  +++ b/src/libsystemd-network/dhcp-internal.h
  @@ -20,22 +20,25 @@
 
 You should have received a copy of the GNU Lesser General Public License
 along with systemd; If not, see http://www.gnu.org/licenses/.
   ***/
 
   #include stdint.h
   #include linux/if_packet.h
  +#include net/if_arp.h
   #include net/ethernet.h
 
   #include socket-util.h
 
   #include sd-dhcp-client.h
   #include dhcp-protocol.h
 
  -int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, 
  uint32_t xid, struct ether_addr mac_addr);
  +int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
  + uint32_t xid, const uint8_t *mac_addr,
  + size_t mac_addr_len, uint16_t arp_type);
   int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
   int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
const void *packet, size_t len);
   int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
const void *packet, size_t len);
 
   int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, 
  uint8_t overload,
  @@ -43,16 +46,17 @@ int dhcp_option_append(DHCPMessage *message, size_t 
  size, size_t *offset, uint8_
 
   typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len,
   const uint8_t *option, void *user_data);
 
   int dhcp_option_parse(DHCPMessage *message, size_t len,
 dhcp_option_cb_t cb, void *user_data);
 
  -int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, 
  uint8_t type,
  -  size_t optlen, size_t *optoffset);
  +int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
  +  uint8_t type, uint16_t arp_type, size_t optlen,
  +  size_t *optoffset);
 
   uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len);
 
   void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
  uint16_t source, be32_t 
  destination_addr,
  uint16_t destination, uint16_t len);
 
  diff --git a/src/libsystemd-network/dhcp-network.c 
  b/src/libsystemd-network/dhcp-network.c
  index 1ced5cf..29e9993 100644
  --- a/src/libsystemd-network/dhcp-network.c
  +++ b/src/libsystemd-network/dhcp-network.c
  @@ -18,27 +18,31 @@
   ***/
 
   #include errno.h
   #include sys/types.h
   #include sys/socket.h
   #include string.h
   #include linux/if_packet.h
  +#include linux/if_infiniband.h
   #include net/ethernet.h
   #include net/if_arp.h
   #include stdio.h
   #include unistd.h
   #include linux/filter.h
 
   #include socket-util.h
 
   #include dhcp-internal.h
 
  -int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
  - uint32_t xid, struct ether_addr mac_addr) 
  {
  -
  +static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
  +uint32_t xid, const uint8_t *mac_addr,
  +size_t mac_addr_len,
  +const uint8_t *bcast_addr,
  +const struct ether_addr *eth_mac,
  +uint16_t arp_type, uint8_t dhcp_hlen) {
   struct sock_filter filter[] = {
   BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), 
  /* A - packet length */
   BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 
  0), /* packet = DHCPPacket ? */
   BPF_STMT(BPF_RET + 

Re: [systemd-devel] [PATCH] sd-dhcp-client: support non-Ethernet hardware addresses

2014-10-02 Thread Tom Gundersen
On Thu, Oct 2, 2014 at 6:07 PM, Dan Williams d...@redhat.com wrote:
 On Thu, 2014-10-02 at 16:39 +0200, Tom Gundersen wrote:
 On Fri, Sep 26, 2014 at 10:15 PM, Dan Williams d...@redhat.com wrote:
  Like Infiniband.  See RFC 4390 section 2.1 for details on DHCP
  and Infiniband; chaddr is zeroed, hlen is set to 0, and htype
  is set to ARPHRD_INFINIBAND because IB hardware addresses
  are 20 bytes in length.

 Sorry for taking time with this. Overall looks good, just minor comments 
 inline.

  ---
   src/libsystemd-network/dhcp-internal.h| 10 +++--
   src/libsystemd-network/dhcp-network.c | 54 -
   src/libsystemd-network/dhcp-packet.c  |  8 ++--
   src/libsystemd-network/sd-dhcp-client.c   | 66 
  +++
   src/libsystemd-network/sd-dhcp-server.c   |  8 ++--
   src/libsystemd-network/test-dhcp-client.c | 14 +--
   src/libsystemd-network/test-dhcp-option.c |  2 +-
   src/network/networkd-dhcp4.c  |  4 +-
   src/network/networkd-link.c   |  4 +-
   src/systemd/sd-dhcp-client.h  |  4 +-
   10 files changed, 130 insertions(+), 44 deletions(-)
 
  *** Testing appreciated
 
  diff --git a/src/libsystemd-network/dhcp-internal.h 
  b/src/libsystemd-network/dhcp-internal.h
  index 1069c8a..d358a49 100644
  --- a/src/libsystemd-network/dhcp-internal.h
  +++ b/src/libsystemd-network/dhcp-internal.h
  @@ -20,22 +20,25 @@
 
 You should have received a copy of the GNU Lesser General Public License
 along with systemd; If not, see http://www.gnu.org/licenses/.
   ***/
 
   #include stdint.h
   #include linux/if_packet.h
  +#include net/if_arp.h
   #include net/ethernet.h
 
   #include socket-util.h
 
   #include sd-dhcp-client.h
   #include dhcp-protocol.h
 
  -int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, 
  uint32_t xid, struct ether_addr mac_addr);
  +int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
  + uint32_t xid, const uint8_t *mac_addr,
  + size_t mac_addr_len, uint16_t arp_type);
   int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
   int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
const void *packet, size_t len);
   int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
const void *packet, size_t len);
 
   int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, 
  uint8_t overload,
  @@ -43,16 +46,17 @@ int dhcp_option_append(DHCPMessage *message, size_t 
  size, size_t *offset, uint8_
 
   typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len,
   const uint8_t *option, void *user_data);
 
   int dhcp_option_parse(DHCPMessage *message, size_t len,
 dhcp_option_cb_t cb, void *user_data);
 
  -int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, 
  uint8_t type,
  -  size_t optlen, size_t *optoffset);
  +int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
  +  uint8_t type, uint16_t arp_type, size_t optlen,
  +  size_t *optoffset);
 
   uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len);
 
   void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
  uint16_t source, be32_t 
  destination_addr,
  uint16_t destination, uint16_t len);
 
  diff --git a/src/libsystemd-network/dhcp-network.c 
  b/src/libsystemd-network/dhcp-network.c
  index 1ced5cf..29e9993 100644
  --- a/src/libsystemd-network/dhcp-network.c
  +++ b/src/libsystemd-network/dhcp-network.c
  @@ -18,27 +18,31 @@
   ***/
 
   #include errno.h
   #include sys/types.h
   #include sys/socket.h
   #include string.h
   #include linux/if_packet.h
  +#include linux/if_infiniband.h
   #include net/ethernet.h
   #include net/if_arp.h
   #include stdio.h
   #include unistd.h
   #include linux/filter.h
 
   #include socket-util.h
 
   #include dhcp-internal.h
 
  -int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
  - uint32_t xid, struct ether_addr 
  mac_addr) {
  -
  +static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
  +uint32_t xid, const uint8_t *mac_addr,
  +size_t mac_addr_len,
  +const uint8_t *bcast_addr,
  +const struct ether_addr *eth_mac,
  +uint16_t arp_type, uint8_t dhcp_hlen) {
   struct sock_filter filter[] = {
   BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),
   /* A - packet length */
   BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 
  1, 0), 

[systemd-devel] [PATCH] sd-dhcp-client: support non-Ethernet hardware addresses

2014-09-26 Thread Dan Williams
Like Infiniband.  See RFC 4390 section 2.1 for details on DHCP
and Infiniband; chaddr is zeroed, hlen is set to 0, and htype
is set to ARPHRD_INFINIBAND because IB hardware addresses
are 20 bytes in length.
---
 src/libsystemd-network/dhcp-internal.h| 10 +++--
 src/libsystemd-network/dhcp-network.c | 54 -
 src/libsystemd-network/dhcp-packet.c  |  8 ++--
 src/libsystemd-network/sd-dhcp-client.c   | 66 +++
 src/libsystemd-network/sd-dhcp-server.c   |  8 ++--
 src/libsystemd-network/test-dhcp-client.c | 14 +--
 src/libsystemd-network/test-dhcp-option.c |  2 +-
 src/network/networkd-dhcp4.c  |  4 +-
 src/network/networkd-link.c   |  4 +-
 src/systemd/sd-dhcp-client.h  |  4 +-
 10 files changed, 130 insertions(+), 44 deletions(-)

*** Testing appreciated

diff --git a/src/libsystemd-network/dhcp-internal.h 
b/src/libsystemd-network/dhcp-internal.h
index 1069c8a..d358a49 100644
--- a/src/libsystemd-network/dhcp-internal.h
+++ b/src/libsystemd-network/dhcp-internal.h
@@ -20,22 +20,25 @@
 
   You should have received a copy of the GNU Lesser General Public License
   along with systemd; If not, see http://www.gnu.org/licenses/.
 ***/
 
 #include stdint.h
 #include linux/if_packet.h
+#include net/if_arp.h
 #include net/ethernet.h
 
 #include socket-util.h
 
 #include sd-dhcp-client.h
 #include dhcp-protocol.h
 
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, 
uint32_t xid, struct ether_addr mac_addr);
+int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
+ uint32_t xid, const uint8_t *mac_addr,
+ size_t mac_addr_len, uint16_t arp_type);
 int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
 int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
  const void *packet, size_t len);
 int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
  const void *packet, size_t len);
 
 int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, 
uint8_t overload,
@@ -43,16 +46,17 @@ int dhcp_option_append(DHCPMessage *message, size_t size, 
size_t *offset, uint8_
 
 typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len,
 const uint8_t *option, void *user_data);
 
 int dhcp_option_parse(DHCPMessage *message, size_t len,
   dhcp_option_cb_t cb, void *user_data);
 
-int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, uint8_t 
type,
-  size_t optlen, size_t *optoffset);
+int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
+  uint8_t type, uint16_t arp_type, size_t optlen,
+  size_t *optoffset);
 
 uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len);
 
 void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
uint16_t source, be32_t destination_addr,
uint16_t destination, uint16_t len);
 
diff --git a/src/libsystemd-network/dhcp-network.c 
b/src/libsystemd-network/dhcp-network.c
index 1ced5cf..29e9993 100644
--- a/src/libsystemd-network/dhcp-network.c
+++ b/src/libsystemd-network/dhcp-network.c
@@ -18,27 +18,31 @@
 ***/
 
 #include errno.h
 #include sys/types.h
 #include sys/socket.h
 #include string.h
 #include linux/if_packet.h
+#include linux/if_infiniband.h
 #include net/ethernet.h
 #include net/if_arp.h
 #include stdio.h
 #include unistd.h
 #include linux/filter.h
 
 #include socket-util.h
 
 #include dhcp-internal.h
 
-int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
- uint32_t xid, struct ether_addr mac_addr) {
-
+static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
+uint32_t xid, const uint8_t *mac_addr,
+size_t mac_addr_len,
+const uint8_t *bcast_addr,
+const struct ether_addr *eth_mac,
+uint16_t arp_type, uint8_t dhcp_hlen) {
 struct sock_filter filter[] = {
 BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), 
/* A - packet length */
 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 0), 
/* packet = DHCPPacket ? */
 BPF_STMT(BPF_RET + BPF_K, 0),  
/* ignore */
 BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, 
ip.protocol)), /* A - IP protocol */
 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0),
/* IP protocol == UDP ? */
 BPF_STMT(BPF_RET + BPF_K, 0),  
/* ignore */
@@ -53,29 +57,29 @@ int