1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-22 13:33:56 +03:00

arp-util: use struct in_addr

This commit is contained in:
Yu Watanabe 2021-06-18 16:02:46 +09:00
parent e1a3915b41
commit ecad63f850
4 changed files with 23 additions and 20 deletions

View File

@ -10,10 +10,11 @@
#include "arp-util.h"
#include "ether-addr-util.h"
#include "fd-util.h"
#include "in-addr-util.h"
#include "unaligned.h"
#include "util.h"
int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) {
int arp_network_bind_raw_socket(int ifindex, const struct in_addr *a, const struct ether_addr *eth_mac) {
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(struct ether_arp), 1, 0), /* packet >= arp packet ? */
@ -47,13 +48,13 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1), /* A == 0 ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
/* Sender Protocol Address or Target Protocol Address must be equal to the one we care about */
BPF_STMT(BPF_LD + BPF_IMM, htobe32(address)), /* A <- clients IP */
BPF_STMT(BPF_LD + BPF_IMM, htobe32(a->s_addr)), /* A <- clients IP */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_spa)), /* A <- SPA */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* X xor A */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1), /* A == 0 ? */
BPF_STMT(BPF_RET + BPF_K, 65535), /* return all */
BPF_STMT(BPF_LD + BPF_IMM, htobe32(address)), /* A <- clients IP */
BPF_STMT(BPF_LD + BPF_IMM, htobe32(a->s_addr)), /* A <- clients IP */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_tpa)), /* A <- TPA */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* X xor A */
@ -92,7 +93,7 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
int arp_send_packet(
int fd,
int ifindex,
be32_t pa,
const struct in_addr *pa,
const struct ether_addr *ha,
bool announce) {
@ -107,22 +108,23 @@ int arp_send_packet(
.ea_hdr.ar_hrd = htobe16(ARPHRD_ETHER), /* HTYPE */
.ea_hdr.ar_pro = htobe16(ETHERTYPE_IP), /* PTYPE */
.ea_hdr.ar_hln = ETH_ALEN, /* HLEN */
.ea_hdr.ar_pln = sizeof(be32_t), /* PLEN */
.ea_hdr.ar_pln = sizeof(struct in_addr), /* PLEN */
.ea_hdr.ar_op = htobe16(ARPOP_REQUEST), /* REQUEST */
};
ssize_t n;
assert(fd >= 0);
assert(ifindex > 0);
assert(pa != 0);
assert(pa);
assert(in4_addr_is_set(pa));
assert(ha);
assert(!ether_addr_is_null(ha));
memcpy(&arp.arp_sha, ha, ETH_ALEN);
memcpy(&arp.arp_tpa, &pa, sizeof(pa));
memcpy(&arp.arp_tpa, pa, sizeof(struct in_addr));
if (announce)
memcpy(&arp.arp_spa, &pa, sizeof(pa));
memcpy(&arp.arp_spa, pa, sizeof(struct in_addr));
n = sendto(fd, &arp, sizeof(struct ether_arp), 0, &link.sa, sizeof(link.ll));
if (n < 0)

View File

@ -6,29 +6,30 @@
***/
#include <net/ethernet.h>
#include <netinet/in.h>
#include "socket-util.h"
#include "sparse-endian.h"
int arp_network_bind_raw_socket(int index, be32_t address, const struct ether_addr *eth_mac);
int arp_network_bind_raw_socket(int index, const struct in_addr *a, const struct ether_addr *eth_mac);
int arp_send_packet(
int fd,
int ifindex,
be32_t pa,
const struct in_addr *pa,
const struct ether_addr *ha,
bool announce);
static inline int arp_send_probe(
int fd,
int ifindex,
be32_t pa,
const struct in_addr *pa,
const struct ether_addr *ha) {
return arp_send_packet(fd, ifindex, pa, ha, false);
}
static inline int arp_send_announcement(
int fd,
int ifindex,
be32_t pa,
const struct in_addr *pa,
const struct ether_addr *ha) {
return arp_send_packet(fd, ifindex, pa, ha, true);
}

View File

@ -213,7 +213,7 @@ static bool ipv4acd_arp_conflict(sd_ipv4acd *acd, struct ether_arp *arp) {
assert(arp);
/* see the BPF */
if (memcmp(arp->arp_spa, &acd->address.s_addr, sizeof(acd->address.s_addr)) == 0)
if (memcmp(arp->arp_spa, &acd->address, sizeof(acd->address)) == 0)
return true;
/* the TPA matched instead of the SPA, this is not a conflict */
@ -249,7 +249,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
case IPV4ACD_STATE_WAITING_PROBE:
case IPV4ACD_STATE_PROBING:
/* Send a probe */
r = arp_send_probe(acd->fd, acd->ifindex, acd->address.s_addr, &acd->mac_addr);
r = arp_send_probe(acd->fd, acd->ifindex, &acd->address, &acd->mac_addr);
if (r < 0) {
log_ipv4acd_errno(acd, r, "Failed to send ARP probe: %m");
goto fail;
@ -282,7 +282,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
_fallthrough_;
case IPV4ACD_STATE_WAITING_ANNOUNCE:
/* Send announcement packet */
r = arp_send_announcement(acd->fd, acd->ifindex, acd->address.s_addr, &acd->mac_addr);
r = arp_send_announcement(acd->fd, acd->ifindex, &acd->address, &acd->mac_addr);
if (r < 0) {
log_ipv4acd_errno(acd, r, "Failed to send ARP announcement: %m");
goto fail;
@ -366,7 +366,7 @@ static int ipv4acd_on_packet(
/* Defend address */
if (ts > acd->defend_window) {
acd->defend_window = ts + DEFEND_INTERVAL_USEC;
r = arp_send_announcement(acd->fd, acd->ifindex, acd->address.s_addr, &acd->mac_addr);
r = arp_send_announcement(acd->fd, acd->ifindex, &acd->address, &acd->mac_addr);
if (r < 0) {
log_ipv4acd_errno(acd, r, "Failed to send ARP announcement: %m");
goto fail;
@ -513,7 +513,7 @@ int sd_ipv4acd_start(sd_ipv4acd *acd, bool reset_conflicts) {
assert_return(!ether_addr_is_null(&acd->mac_addr), -EINVAL);
assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY);
r = arp_network_bind_raw_socket(acd->ifindex, acd->address.s_addr, &acd->mac_addr);
r = arp_network_bind_raw_socket(acd->ifindex, &acd->address, &acd->mac_addr);
if (r < 0)
return r;

View File

@ -45,7 +45,7 @@ static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
int arp_send_packet(
int fd,
int ifindex,
be32_t pa,
const struct in_addr *pa,
const struct ether_addr *ha,
bool announce) {
@ -53,7 +53,7 @@ int arp_send_packet(
assert_se(fd >= 0);
assert_se(ifindex > 0);
assert_se(pa != 0);
assert_se(pa);
assert_se(ha);
if (send(fd, &ea, sizeof(struct ether_arp), 0) < 0)
@ -62,7 +62,7 @@ int arp_send_packet(
return 0;
}
int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) {
int arp_network_bind_raw_socket(int ifindex, const struct in_addr *a, const struct ether_addr *eth_mac) {
if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
return -errno;