diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libsystemd-network/dhcp-internal.h | 3 | ||||
-rw-r--r-- | src/libsystemd-network/dhcp-network.c | 15 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-client.c | 4 | ||||
-rw-r--r-- | src/libsystemd-network/test-dhcp-client.c | 2 |
4 files changed, 18 insertions, 6 deletions
diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h index 6f6f1218d9..1069c8a03b 100644 --- a/src/libsystemd-network/dhcp-internal.h +++ b/src/libsystemd-network/dhcp-internal.h @@ -24,13 +24,14 @@ #include <stdint.h> #include <linux/if_packet.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); +int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t xid, struct ether_addr mac_addr); 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); diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c index 9d579177a4..f119cae7ff 100644 --- a/src/libsystemd-network/dhcp-network.c +++ b/src/libsystemd-network/dhcp-network.c @@ -33,7 +33,7 @@ #include "dhcp-internal.h" int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, - uint32_t xid) { + uint32_t xid, struct ether_addr mac_addr) { 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 ? */ @@ -60,7 +60,18 @@ int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), /* client identifier == xid ? */ BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ - /* TODO: match chaddr */ + BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) &mac_addr))), /* A <- 4 bytes of client's MAC */ + BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */ + BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) (((char *) &mac_addr) + 4)))), /* A <- remainder of client's MAC */ + BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4), /* A <- remainder of MAC from dhcp.chaddr */ + BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.magic)), /* A <- DHCP magic cookie */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_MAGIC_COOKIE, 1, 0), /* cookie == DHCP magic cookie ? */ BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index d8a9d20e4c..6b19666c3b 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -751,7 +751,7 @@ static int client_start(sd_dhcp_client *client) { client->xid = random_u32(); - r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid); + r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr); if (r < 0) { client_stop(client, r); return r; @@ -795,7 +795,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) client->state = DHCP_STATE_REBINDING; client->attempt = 1; - r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid); + r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr); if (r < 0) { client_stop(client, r); return 0; diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index 450b6d4d3c..7cbe10d5a7 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -196,7 +196,7 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, return 575; } -int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t id) +int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t id, struct ether_addr mac) { if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0) return -errno; |