From e804e6f9a02c3531e7a000de016d3b7a456c0ac6 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Tue, 22 Apr 2014 16:00:59 +0200 Subject: [PATCH] Common type holding an address This modifies all transports to use a new common address type, struct address. This address is stored in a ptp_message for all received messages. For sending, the "default" address is used with the default sending functions, transport_send and transport_peer. The default address depends on the transport; it's supposed to be the multicast address assigned by the transport specification. Later, a new transport_sendto function will be implemented that sends to the address contained in the passed ptp_message. Signed-off-by: Jiri Benc --- address.h | 38 ++++++++++++++++++++++++ msg.h | 6 ++++ raw.c | 50 ++++++++++++++++++++------------ sk.c | 34 +++++++++++++--------- sk.h | 11 +++---- transport.c | 6 ++-- transport_private.h | 8 ++++-- udp.c | 66 +++++++++++++++++++++++++----------------- udp6.c | 70 ++++++++++++++++++++++++++------------------- uds.c | 27 ++++++++++------- util.c | 18 ++++++------ 11 files changed, 217 insertions(+), 117 deletions(-) create mode 100644 address.h diff --git a/address.h b/address.h new file mode 100644 index 0000000..b780387 --- /dev/null +++ b/address.h @@ -0,0 +1,38 @@ +/** + * @file address.h + * @brief Definition of a structure to hold an address. + * @note Copyright (C) 2014 Red Hat, Inc., Jiri Benc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef HAVE_ADDRESS_H +#define HAVE_ADDRESS_H + +#include +#include +#include + +struct address { + socklen_t len; + union { + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + struct sockaddr_un sun; + struct sockaddr sa; + }; +}; + +#endif diff --git a/msg.h b/msg.h index 564cc9b..3fa5833 100644 --- a/msg.h +++ b/msg.h @@ -24,6 +24,7 @@ #include #include +#include "address.h" #include "ddt.h" #include "tlv.h" @@ -213,6 +214,11 @@ struct ptp_message { * SO_TIMESTAMPING socket option. */ struct hw_timestamp hwts; + /** + * Contains the address this message was received from or should be + * sent to. + */ + struct address address; /** * Contains the number of TLVs in the suffix. */ diff --git a/raw.c b/raw.c index 2de0793..cd7bd90 100644 --- a/raw.c +++ b/raw.c @@ -36,6 +36,7 @@ #include #include +#include "address.h" #include "contain.h" #include "ether.h" #include "print.h" @@ -45,9 +46,9 @@ struct raw { struct transport t; - eth_addr src_addr; - eth_addr ptp_addr; - eth_addr p2p_addr; + struct address src_addr; + struct address ptp_addr; + struct address p2p_addr; int vlan; }; @@ -185,16 +186,28 @@ no_socket: return -1; } +static void mac_to_addr(struct address *addr, void *mac) +{ + addr->sa.sa_family = AF_UNSPEC; + memcpy(&addr->sa.sa_data, mac, MAC_LEN); + addr->len = sizeof(addr->sa.sa_family) + MAC_LEN; +} + +static void addr_to_mac(void *mac, struct address *addr) +{ + memcpy(mac, &addr->sa.sa_data, MAC_LEN); +} + static int raw_open(struct transport *t, const char *name, struct fdarray *fda, enum timestamp_type ts_type) { struct raw *raw = container_of(t, struct raw, t); int efd, gfd; - memcpy(raw->ptp_addr, ptp_dst_mac, MAC_LEN); - memcpy(raw->p2p_addr, p2p_dst_mac, MAC_LEN); + mac_to_addr(&raw->ptp_addr, ptp_dst_mac); + mac_to_addr(&raw->p2p_addr, p2p_dst_mac); - if (sk_interface_macaddr(name, raw->src_addr, MAC_LEN)) + if (sk_interface_macaddr(name, &raw->src_addr)) goto no_mac; efd = open_socket(name, 1); @@ -225,7 +238,7 @@ no_mac: } static int raw_recv(struct transport *t, int fd, void *buf, int buflen, - struct hw_timestamp *hwts) + struct address *addr, struct hw_timestamp *hwts) { int cnt, hlen; unsigned char *ptr = buf; @@ -241,7 +254,7 @@ static int raw_recv(struct transport *t, int fd, void *buf, int buflen, buflen += hlen; hdr = (struct eth_hdr *) ptr; - cnt = sk_receive(fd, ptr, buflen, hwts, 0); + cnt = sk_receive(fd, ptr, buflen, addr, hwts, 0); if (cnt >= 0) cnt -= hlen; @@ -262,8 +275,9 @@ static int raw_recv(struct transport *t, int fd, void *buf, int buflen, return cnt; } -static int raw_send(struct transport *t, struct fdarray *fda, int event, int peer, - void *buf, int len, struct hw_timestamp *hwts) +static int raw_send(struct transport *t, struct fdarray *fda, int event, + int peer, void *buf, int len, struct address *addr, + struct hw_timestamp *hwts) { struct raw *raw = container_of(t, struct raw, t); ssize_t cnt; @@ -274,12 +288,12 @@ static int raw_send(struct transport *t, struct fdarray *fda, int event, int pee ptr -= sizeof(*hdr); len += sizeof(*hdr); + if (!addr) + addr = peer ? &raw->p2p_addr : &raw->ptp_addr; + hdr = (struct eth_hdr *) ptr; - if (peer) - memcpy(&hdr->dst, &raw->p2p_addr, MAC_LEN); - else - memcpy(&hdr->dst, &raw->ptp_addr, MAC_LEN); - memcpy(&hdr->src, &raw->src_addr, MAC_LEN); + addr_to_mac(&hdr->dst, addr); + addr_to_mac(&hdr->src, &raw->src_addr); hdr->type = htons(ETH_P_1588); @@ -291,7 +305,7 @@ static int raw_send(struct transport *t, struct fdarray *fda, int event, int pee /* * Get the time stamp right away. */ - return event == TRANS_EVENT ? sk_receive(fd, pkt, len, hwts, MSG_ERRQUEUE) : cnt; + return event == TRANS_EVENT ? sk_receive(fd, pkt, len, NULL, hwts, MSG_ERRQUEUE) : cnt; } static void raw_release(struct transport *t) @@ -303,14 +317,14 @@ static void raw_release(struct transport *t) static int raw_physical_addr(struct transport *t, uint8_t *addr) { struct raw *raw = container_of(t, struct raw, t); - memcpy(addr, raw->src_addr, MAC_LEN); + addr_to_mac(addr, &raw->src_addr); return MAC_LEN; } static int raw_protocol_addr(struct transport *t, uint8_t *addr) { struct raw *raw = container_of(t, struct raw, t); - memcpy(addr, raw->src_addr, MAC_LEN); + addr_to_mac(addr, &raw->src_addr); return MAC_LEN; } diff --git a/sk.c b/sk.c index 8d70d1a..838004e 100644 --- a/sk.c +++ b/sk.c @@ -30,6 +30,8 @@ #include #include +#include "address.h" +#include "ether.h" #include "print.h" #include "sk.h" @@ -146,7 +148,7 @@ failed: return -1; } -int sk_interface_macaddr(const char *name, unsigned char *mac, int len) +int sk_interface_macaddr(const char *name, struct address *mac) { struct ifreq ifreq; int err, fd; @@ -167,16 +169,17 @@ int sk_interface_macaddr(const char *name, unsigned char *mac, int len) return -1; } - memcpy(mac, ifreq.ifr_hwaddr.sa_data, len); + memcpy(&mac->sa, &ifreq.ifr_hwaddr, sizeof(ifreq.ifr_hwaddr)); + mac->len = sizeof(ifreq.ifr_hwaddr.sa_family) + MAC_LEN; close(fd); return 0; } -int sk_interface_addr(const char *name, int family, uint8_t *addr, int len) +int sk_interface_addr(const char *name, int family, struct address *addr) { struct ifaddrs *ifaddr, *i; - int copy_len, result = -1; - void *copy_from; + int result = -1; + if (getifaddrs(&ifaddr) == -1) { pr_err("getifaddrs failed: %m"); return -1; @@ -187,20 +190,16 @@ int sk_interface_addr(const char *name, int family, uint8_t *addr, int len) { switch (family) { case AF_INET: - copy_len = 4; - copy_from = &((struct sockaddr_in *)i->ifa_addr)->sin_addr.s_addr; + addr->len = sizeof(addr->sin); break; case AF_INET6: - copy_len = 16; - copy_from = &((struct sockaddr_in6 *)i->ifa_addr)->sin6_addr.s6_addr; + addr->len = sizeof(addr->sin6); break; default: continue; } - if (copy_len > len) - copy_len = len; - memcpy(addr, copy_from, copy_len); - result = copy_len; + memcpy(&addr->sa, &i->ifa_addr, addr->len); + result = 0; break; } } @@ -209,7 +208,7 @@ int sk_interface_addr(const char *name, int family, uint8_t *addr, int len) } int sk_receive(int fd, void *buf, int buflen, - struct hw_timestamp *hwts, int flags) + struct address *addr, struct hw_timestamp *hwts, int flags) { char control[256]; int cnt = 0, res = 0, level, type; @@ -220,6 +219,10 @@ int sk_receive(int fd, void *buf, int buflen, memset(control, 0, sizeof(control)); memset(&msg, 0, sizeof(msg)); + if (addr) { + msg.msg_name = &addr->ss; + msg.msg_namelen = sizeof(addr->ss); + } msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = control; @@ -265,6 +268,9 @@ int sk_receive(int fd, void *buf, int buflen, } } + if (addr) + addr->len = msg.msg_namelen; + if (!ts) { memset(&hwts->ts, 0, sizeof(hwts->ts)); return cnt; diff --git a/sk.h b/sk.h index ea338c1..f05d1df 100644 --- a/sk.h +++ b/sk.h @@ -20,6 +20,7 @@ #ifndef HAVE_SK_H #define HAVE_SK_H +#include "address.h" #include "transport.h" /** @@ -65,32 +66,32 @@ int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info); * Obtain the MAC address of a network interface. * @param name The name of the interface * @param mac Buffer to hold the result - * @param len Length of 'mac' * @return Zero on success, non-zero otherwise. */ -int sk_interface_macaddr(const char *name, unsigned char *mac, int len); +int sk_interface_macaddr(const char *name, struct address *mac); /** * Obtains the first IP address assigned to a network interface. * @param name The name of the interface * @param family The family of the address to get: AF_INET or AF_INET6 * @param addr Buffer to hold the result - * @param len Length of 'addr' * @return The number of bytes written to addr on success, -1 otherwise. */ -int sk_interface_addr(const char *name, int family, uint8_t *addr, int len); +int sk_interface_addr(const char *name, int family, struct address *addr); /** * Read a message from a socket. * @param fd An open socket. * @param buf Buffer to receive the message. * @param buflen Size of 'buf' in bytes. + * @param addr Pointer to a buffer to receive the message's source + * address. May be NULL. * @param hwts Pointer to a buffer to receive the message's time stamp. * @param flags Flags to pass to RECV(2). * @return */ int sk_receive(int fd, void *buf, int buflen, - struct hw_timestamp *hwts, int flags); + struct address *addr, struct hw_timestamp *hwts, int flags); /** * Enable time stamping on a given network interface. diff --git a/transport.c b/transport.c index cb799a6..b2d4dd1 100644 --- a/transport.c +++ b/transport.c @@ -39,7 +39,7 @@ int transport_open(struct transport *t, const char *name, int transport_recv(struct transport *t, int fd, struct ptp_message *msg) { - return t->recv(t, fd, msg, sizeof(msg->data), &msg->hwts); + return t->recv(t, fd, msg, sizeof(msg->data), &msg->address, &msg->hwts); } int transport_send(struct transport *t, struct fdarray *fda, int event, @@ -47,7 +47,7 @@ int transport_send(struct transport *t, struct fdarray *fda, int event, { int len = ntohs(msg->header.messageLength); - return t->send(t, fda, event, 0, msg, len, &msg->hwts); + return t->send(t, fda, event, 0, msg, len, NULL, &msg->hwts); } int transport_peer(struct transport *t, struct fdarray *fda, int event, @@ -55,7 +55,7 @@ int transport_peer(struct transport *t, struct fdarray *fda, int event, { int len = ntohs(msg->header.messageLength); - return t->send(t, fda, event, 1, msg, len, &msg->hwts); + return t->send(t, fda, event, 1, msg, len, NULL, &msg->hwts); } int transport_physical_addr(struct transport *t, uint8_t *addr) diff --git a/transport_private.h b/transport_private.h index 7124f94..3e0ba9a 100644 --- a/transport_private.h +++ b/transport_private.h @@ -22,6 +22,7 @@ #include +#include "address.h" #include "fd.h" #include "transport.h" @@ -34,10 +35,11 @@ struct transport { enum timestamp_type tt); int (*recv)(struct transport *t, int fd, void *buf, int buflen, - struct hw_timestamp *hwts); + struct address *addr, struct hw_timestamp *hwts); - int (*send)(struct transport *t, struct fdarray *fda, int event, int peer, - void *buf, int buflen, struct hw_timestamp *hwts); + int (*send)(struct transport *t, struct fdarray *fda, int event, + int peer, void *buf, int buflen, struct address *addr, + struct hw_timestamp *hwts); void (*release)(struct transport *t); diff --git a/udp.c b/udp.c index 818cbfd..b100dbf 100644 --- a/udp.c +++ b/udp.c @@ -29,6 +29,7 @@ #include #include +#include "address.h" #include "contain.h" #include "print.h" #include "sk.h" @@ -43,10 +44,8 @@ struct udp { struct transport t; - uint8_t ip[4]; - int ip_len; - uint8_t mac[MAC_LEN]; - int mac_len; + struct address ip; + struct address mac; }; static int mcast_bind(int fd, int index) @@ -154,13 +153,11 @@ static int udp_open(struct transport *t, const char *name, struct fdarray *fda, struct udp *udp = container_of(t, struct udp, t); int efd, gfd; - udp->mac_len = 0; - if (sk_interface_macaddr(name, udp->mac, MAC_LEN) == 0) - udp->mac_len = MAC_LEN; + udp->mac.len = 0; + sk_interface_macaddr(name, &udp->mac); - udp->ip_len = sk_interface_addr(name, AF_INET, udp->ip, sizeof(udp->ip)); - if (udp->ip_len == -1) - udp->ip_len = 0; + udp->ip.len = 0; + sk_interface_addr(name, AF_INET, &udp->ip); if (!inet_aton(PTP_PRIMARY_MCAST_IPADDR, &mcast_addr[MC_PRIMARY])) return -1; @@ -195,23 +192,30 @@ no_event: } static int udp_recv(struct transport *t, int fd, void *buf, int buflen, - struct hw_timestamp *hwts) + struct address *addr, struct hw_timestamp *hwts) { - return sk_receive(fd, buf, buflen, hwts, 0); + return sk_receive(fd, buf, buflen, addr, hwts, 0); } -static int udp_send(struct transport *t, struct fdarray *fda, int event, int peer, - void *buf, int len, struct hw_timestamp *hwts) +static int udp_send(struct transport *t, struct fdarray *fda, int event, + int peer, void *buf, int len, struct address *addr, + struct hw_timestamp *hwts) { ssize_t cnt; int fd = event ? fda->fd[FD_EVENT] : fda->fd[FD_GENERAL]; - struct sockaddr_in addr; + struct address addr_buf; unsigned char junk[1600]; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr = peer ? mcast_addr[MC_PDELAY] : mcast_addr[MC_PRIMARY]; - addr.sin_port = htons(event ? EVENT_PORT : GENERAL_PORT); + if (!addr) { + memset(&addr_buf, 0, sizeof(addr_buf)); + addr_buf.sin.sin_family = AF_INET; + addr_buf.sin.sin_addr = peer ? mcast_addr[MC_PDELAY] : + mcast_addr[MC_PRIMARY]; + addr_buf.sin.sin_port = htons(event ? EVENT_PORT : + GENERAL_PORT); + addr_buf.len = sizeof(addr_buf.sin); + addr = &addr_buf; + } /* * Extend the payload by two, for UDP checksum correction. @@ -221,7 +225,7 @@ static int udp_send(struct transport *t, struct fdarray *fda, int event, int pee if (event == TRANS_ONESTEP) len += 2; - cnt = sendto(fd, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr)); + cnt = sendto(fd, buf, len, 0, &addr->sa, sizeof(addr->sin)); if (cnt < 1) { pr_err("sendto failed: %m"); return cnt; @@ -229,7 +233,7 @@ static int udp_send(struct transport *t, struct fdarray *fda, int event, int pee /* * Get the time stamp right away. */ - return event == TRANS_EVENT ? sk_receive(fd, junk, len, hwts, MSG_ERRQUEUE) : cnt; + return event == TRANS_EVENT ? sk_receive(fd, junk, len, NULL, hwts, MSG_ERRQUEUE) : cnt; } static void udp_release(struct transport *t) @@ -241,17 +245,25 @@ static void udp_release(struct transport *t) static int udp_physical_addr(struct transport *t, uint8_t *addr) { struct udp *udp = container_of(t, struct udp, t); - if (udp->mac_len) - memcpy(addr, udp->mac, udp->mac_len); - return udp->mac_len; + int len = 0; + + if (udp->mac.len) { + len = MAC_LEN; + memcpy(addr, udp->mac.sa.sa_data, len); + } + return len; } static int udp_protocol_addr(struct transport *t, uint8_t *addr) { struct udp *udp = container_of(t, struct udp, t); - if (udp->ip_len) - memcpy(addr, &udp->ip, udp->ip_len); - return udp->ip_len; + int len = 0; + + if (udp->ip.len) { + len = sizeof(udp->ip.sin.sin_addr.s_addr); + memcpy(addr, &udp->ip.sin.sin_addr.s_addr, len); + } + return len; } struct transport *udp_transport_create(void) diff --git a/udp6.c b/udp6.c index e26195b..f098b8c 100644 --- a/udp6.c +++ b/udp6.c @@ -29,6 +29,7 @@ #include #include +#include "address.h" #include "contain.h" #include "print.h" #include "sk.h" @@ -46,10 +47,8 @@ unsigned char udp6_scope = 0x0E; struct udp6 { struct transport t; int index; - uint8_t ip[16]; - int ip_len; - uint8_t mac[MAC_LEN]; - int mac_len; + struct address ip; + struct address mac; }; static int is_link_local(struct in6_addr *addr) @@ -164,13 +163,11 @@ static int udp6_open(struct transport *t, const char *name, struct fdarray *fda, struct udp6 *udp6 = container_of(t, struct udp6, t); int efd, gfd; - udp6->mac_len = 0; - if (sk_interface_macaddr(name, udp6->mac, MAC_LEN) == 0) - udp6->mac_len = MAC_LEN; + udp6->mac.len = 0; + sk_interface_macaddr(name, &udp6->mac); - udp6->ip_len = sk_interface_addr(name, AF_INET6, udp6->ip, sizeof(udp6->ip)); - if (udp6->ip_len == -1) - udp6->ip_len = 0; + udp6->ip.len = 0; + sk_interface_addr(name, AF_INET6, &udp6->ip); if (1 != inet_pton(AF_INET6, PTP_PRIMARY_MCAST_IP6ADDR, &mc6_addr[MC_PRIMARY])) return -1; @@ -207,32 +204,39 @@ no_event: } static int udp6_recv(struct transport *t, int fd, void *buf, int buflen, - struct hw_timestamp *hwts) + struct address *addr, struct hw_timestamp *hwts) { - return sk_receive(fd, buf, buflen, hwts, 0); + return sk_receive(fd, buf, buflen, addr, hwts, 0); } -static int udp6_send(struct transport *t, struct fdarray *fda, int event, int peer, - void *buf, int len, struct hw_timestamp *hwts) +static int udp6_send(struct transport *t, struct fdarray *fda, int event, + int peer, void *buf, int len, struct address *addr, + struct hw_timestamp *hwts) { struct udp6 *udp6 = container_of(t, struct udp6, t); ssize_t cnt; int fd = event ? fda->fd[FD_EVENT] : fda->fd[FD_GENERAL]; - struct sockaddr_in6 addr; + struct address addr_buf; unsigned char junk[1600]; - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_addr = peer ? mc6_addr[MC_PDELAY] : mc6_addr[MC_PRIMARY]; - addr.sin6_port = htons(event ? EVENT_PORT : GENERAL_PORT); + if (!addr) { + memset(&addr_buf, 0, sizeof(addr_buf)); + addr_buf.sin6.sin6_family = AF_INET6; + addr_buf.sin6.sin6_addr = peer ? mc6_addr[MC_PDELAY] : + mc6_addr[MC_PRIMARY]; + addr_buf.sin6.sin6_port = htons(event ? EVENT_PORT : + GENERAL_PORT); - if (is_link_local(&addr.sin6_addr)) { - addr.sin6_scope_id = udp6->index; + if (is_link_local(&addr_buf.sin6.sin6_addr)) + addr_buf.sin6.sin6_scope_id = udp6->index; + + addr_buf.len = sizeof(addr_buf.sin6); + addr = &addr_buf; } len += 2; /* Extend the payload by two, for UDP checksum corrections. */ - cnt = sendto(fd, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr)); + cnt = sendto(fd, buf, len, 0, &addr->sa, sizeof(addr->sin6)); if (cnt < 1) { pr_err("sendto failed: %m"); return cnt; @@ -240,7 +244,7 @@ static int udp6_send(struct transport *t, struct fdarray *fda, int event, int pe /* * Get the time stamp right away. */ - return event == TRANS_EVENT ? sk_receive(fd, junk, len, hwts, MSG_ERRQUEUE) : cnt; + return event == TRANS_EVENT ? sk_receive(fd, junk, len, NULL, hwts, MSG_ERRQUEUE) : cnt; } static void udp6_release(struct transport *t) @@ -252,17 +256,25 @@ static void udp6_release(struct transport *t) static int udp6_physical_addr(struct transport *t, uint8_t *addr) { struct udp6 *udp6 = container_of(t, struct udp6, t); - if (udp6->mac_len) - memcpy(addr, udp6->mac, udp6->mac_len); - return udp6->mac_len; + int len = 0; + + if (udp6->mac.len) { + len = MAC_LEN; + memcpy(addr, udp6->mac.sa.sa_data, len); + } + return len; } static int udp6_protocol_addr(struct transport *t, uint8_t *addr) { struct udp6 *udp6 = container_of(t, struct udp6, t); - if (udp6->ip_len) - memcpy(addr, &udp6->ip, udp6->ip_len); - return udp6->ip_len; + int len = 0; + + if (udp6->ip.len) { + len = sizeof(udp6->ip.sin6.sin6_addr.s6_addr); + memcpy(addr, &udp6->ip.sin6.sin6_addr.s6_addr, len); + } + return len; } struct transport *udp6_transport_create(void) diff --git a/uds.c b/uds.c index 35f5ecc..e88b333 100644 --- a/uds.c +++ b/uds.c @@ -25,6 +25,7 @@ #include #include +#include "address.h" #include "contain.h" #include "print.h" #include "transport_private.h" @@ -36,8 +37,7 @@ char uds_path[MAX_IFNAME_SIZE + 1] = "/var/run/ptp4l"; struct uds { struct transport t; - struct sockaddr_un sa; - socklen_t len; + struct address address; }; static int uds_close(struct transport *t, struct fdarray *fda) @@ -75,8 +75,8 @@ static int uds_open(struct transport *t, const char *name, struct fdarray *fda, memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_LOCAL; strncpy(sa.sun_path, uds_path, sizeof(sa.sun_path) - 1); - uds->sa = sa; - uds->len = sizeof(sa); + uds->address.sun = sa; + uds->address.len = sizeof(sa); chmod(name, UDS_FILEMODE); fda->fd[FD_EVENT] = -1; @@ -85,25 +85,32 @@ static int uds_open(struct transport *t, const char *name, struct fdarray *fda, } static int uds_recv(struct transport *t, int fd, void *buf, int buflen, - struct hw_timestamp *hwts) + struct address *addr, struct hw_timestamp *hwts) { int cnt; struct uds *uds = container_of(t, struct uds, t); - socklen_t *len = &uds->len; - uds->len = sizeof(uds->sa); - cnt = recvfrom(fd, buf, buflen, 0, (struct sockaddr *) &uds->sa, len); + + addr->len = sizeof(addr->sun); + cnt = recvfrom(fd, buf, buflen, 0, &addr->sa, &addr->len); if (cnt <= 0) { pr_err("uds: recvfrom failed: %m"); + return cnt; } + uds->address = *addr; return cnt; } static int uds_send(struct transport *t, struct fdarray *fda, int event, - int peer, void *buf, int buflen, struct hw_timestamp *hwts) + int peer, void *buf, int buflen, struct address *addr, + struct hw_timestamp *hwts) { int cnt, fd = fda->fd[FD_GENERAL]; struct uds *uds = container_of(t, struct uds, t); - cnt = sendto(fd, buf, buflen, 0, (struct sockaddr *) &uds->sa, uds->len); + + if (!addr) + addr = &uds->address; + + cnt = sendto(fd, buf, buflen, 0, &addr->sa, addr->len); if (cnt <= 0) { pr_err("uds: sendto failed: %m"); } diff --git a/util.c b/util.c index 56af8ef..1e86040 100644 --- a/util.c +++ b/util.c @@ -21,6 +21,7 @@ #include #include +#include "address.h" #include "sk.h" #include "util.h" @@ -100,17 +101,18 @@ int str2pid(const char *s, struct PortIdentity *result) int generate_clock_identity(struct ClockIdentity *ci, const char *name) { - unsigned char mac[6]; - if (sk_interface_macaddr(name, mac, sizeof(mac))) + struct address addr; + + if (sk_interface_macaddr(name, &addr)) return -1; - ci->id[0] = mac[0]; - ci->id[1] = mac[1]; - ci->id[2] = mac[2]; + ci->id[0] = addr.sa.sa_data[0]; + ci->id[1] = addr.sa.sa_data[1]; + ci->id[2] = addr.sa.sa_data[2]; ci->id[3] = 0xFF; ci->id[4] = 0xFE; - ci->id[5] = mac[3]; - ci->id[6] = mac[4]; - ci->id[7] = mac[5]; + ci->id[5] = addr.sa.sa_data[3]; + ci->id[6] = addr.sa.sa_data[4]; + ci->id[7] = addr.sa.sa_data[5]; return 0; }