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 <***@redhat.com>
---
address.h | 38 ++++++++++++++++++++++++
msg.h | 6 ++++
raw.c | 56 ++++++++++++++++++++++++-----------
sk.c | 34 ++++++++++++---------
sk.h | 11 ++++---
transport.c | 8 +++--
transport_private.h | 11 +++++--
udp.c | 70 ++++++++++++++++++++++++++-----------------
udp6.c | 81 ++++++++++++++++++++++++++++++---------------------
uds.c | 34 ++++++++++++++-------
util.c | 18 ++++++-----
11 files changed, 244 insertions(+), 123 deletions(-)
create mode 100644 address.h
diff --git a/address.h b/address.h
new file mode 100644
index 000000000000..b7803879f8b2
--- /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 <***@redhat.com>
+ *
+ * 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 <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+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 564cc9bfa0df..3fa58338f07a 100644
--- a/msg.h
+++ b/msg.h
@@ -24,6 +24,7 @@
#include <sys/queue.h>
#include <time.h>
+#include "address.h"
#include "ddt.h"
#include "tlv.h"
@@ -214,6 +215,11 @@ struct ptp_message {
*/
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.
*/
int tlv_count;
diff --git a/raw.c b/raw.c
index 2de0793745ee..b71dbc7f5f88 100644
--- a/raw.c
+++ b/raw.c
@@ -36,6 +36,7 @@
#include <linux/net_tstamp.h>
#include <linux/sockios.h>
+#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,
+ void *buf, int len, struct address *addr,
+ struct hw_timestamp *hwts)
{
struct raw *raw = container_of(t, struct raw, t);
ssize_t cnt;
@@ -275,11 +289,8 @@ static int raw_send(struct transport *t, struct fdarray *fda, int event, int pee
len += sizeof(*hdr);
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 +302,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)
@@ -300,17 +311,25 @@ static void raw_release(struct transport *t)
free(raw);
}
+static struct address *raw_default_addr(struct transport *t,
+ int event, int peer)
+{
+ struct raw *raw = container_of(t, struct raw, t);
+
+ return peer ? &raw->p2p_addr : &raw->ptp_addr;
+}
+
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;
}
@@ -325,6 +344,7 @@ struct transport *raw_transport_create(void)
raw->t.recv = raw_recv;
raw->t.send = raw_send;
raw->t.release = raw_release;
+ raw->t.default_addr = raw_default_addr;
raw->t.physical_addr = raw_physical_addr;
raw->t.protocol_addr = raw_protocol_addr;
return &raw->t;
diff --git a/sk.c b/sk.c
index 8d70d1acf5dd..838004eab14e 100644
--- a/sk.c
+++ b/sk.c
@@ -30,6 +30,8 @@
#include <stdlib.h>
#include <poll.h>
+#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 ea338c13f021..f05d1df5ff86 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 cb799a68aa9f..25d569607f71 100644
--- a/transport.c
+++ b/transport.c
@@ -39,23 +39,25 @@ 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,
struct ptp_message *msg)
{
int len = ntohs(msg->header.messageLength);
+ struct address *addr = t->default_addr(t, event, 0);
- return t->send(t, fda, event, 0, msg, len, &msg->hwts);
+ return t->send(t, fda, event, msg, len, addr, &msg->hwts);
}
int transport_peer(struct transport *t, struct fdarray *fda, int event,
struct ptp_message *msg)
{
int len = ntohs(msg->header.messageLength);
+ struct address *addr = t->default_addr(t, event, 1);
- return t->send(t, fda, event, 1, msg, len, &msg->hwts);
+ return t->send(t, fda, event, msg, len, addr, &msg->hwts);
}
int transport_physical_addr(struct transport *t, uint8_t *addr)
diff --git a/transport_private.h b/transport_private.h
index 7124f94af424..d9302e218f81 100644
--- a/transport_private.h
+++ b/transport_private.h
@@ -22,6 +22,7 @@
#include <time.h>
+#include "address.h"
#include "fd.h"
#include "transport.h"
@@ -34,13 +35,17 @@ 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,
+ void *buf, int buflen, struct address *addr,
+ struct hw_timestamp *hwts);
void (*release)(struct transport *t);
+ struct address *(*default_addr)(struct transport *t,
+ int event, int peer);
+
int (*physical_addr)(struct transport *t, uint8_t *addr);
int (*protocol_addr)(struct transport *t, uint8_t *addr);
diff --git a/udp.c b/udp.c
index 818cbfd53b6a..9f8ac2825ef2 100644
--- a/udp.c
+++ b/udp.c
@@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <unistd.h>
+#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,24 +192,19 @@ 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,
+ 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;
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);
-
/*
* Extend the payload by two, for UDP checksum correction.
* This is not really part of the standard, but it is the way
@@ -221,7 +213,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 +221,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)
@@ -238,20 +230,41 @@ static void udp_release(struct transport *t)
free(udp);
}
+static struct address *udp_default_addr(struct transport *t,
+ int event, int peer)
+{
+ static struct address addr;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin.sin_family = AF_INET;
+ addr.sin.sin_addr = peer ? mcast_addr[MC_PDELAY] : mcast_addr[MC_PRIMARY];
+ addr.sin.sin_port = htons(event ? EVENT_PORT : GENERAL_PORT);
+ addr.len = sizeof(addr.sin);
+ return &addr;
+}
+
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)
@@ -264,6 +277,7 @@ struct transport *udp_transport_create(void)
udp->t.recv = udp_recv;
udp->t.send = udp_send;
udp->t.release = udp_release;
+ udp->t.default_addr = udp_default_addr;
udp->t.physical_addr = udp_physical_addr;
udp->t.protocol_addr = udp_protocol_addr;
return &udp->t;
diff --git a/udp6.c b/udp6.c
index e26195b4fffd..aaad02804c95 100644
--- a/udp6.c
+++ b/udp6.c
@@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <unistd.h>
+#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,22 @@ 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,
+ 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;
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 (is_link_local(&addr.sin6_addr)) {
- addr.sin6_scope_id = udp6->index;
- }
-
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 +227,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)
@@ -249,20 +236,47 @@ static void udp6_release(struct transport *t)
free(udp6);
}
+static struct address *udp6_default_addr(struct transport *t,
+ int event, int peer)
+{
+ struct udp6 *udp6 = container_of(t, struct udp6, t);
+ static struct address addr;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6.sin6_family = AF_INET6;
+ addr.sin6.sin6_addr = peer ? mc6_addr[MC_PDELAY] : mc6_addr[MC_PRIMARY];
+ addr.sin6.sin6_port = htons(event ? EVENT_PORT : GENERAL_PORT);
+
+ if (is_link_local(&addr.sin6.sin6_addr)) {
+ addr.sin6.sin6_scope_id = udp6->index;
+ }
+
+ addr.len = sizeof(addr.sin6);
+ return &addr;
+}
+
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)
@@ -276,6 +290,7 @@ struct transport *udp6_transport_create(void)
udp6->t.recv = udp6_recv;
udp6->t.send = udp6_send;
udp6->t.release = udp6_release;
+ udp6->t.default_addr = udp6_default_addr;
udp6->t.physical_addr = udp6_physical_addr;
udp6->t.protocol_addr = udp6_protocol_addr;
return &udp6->t;
diff --git a/uds.c b/uds.c
index 35f5eccf0545..0ed28658437b 100644
--- a/uds.c
+++ b/uds.c
@@ -25,6 +25,7 @@
#include <sys/un.h>
#include <unistd.h>
+#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,28 @@ 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)
+ 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);
+
+ cnt = sendto(fd, buf, buflen, 0, &addr->sa, addr->len);
if (cnt <= 0) {
pr_err("uds: sendto failed: %m");
}
@@ -116,6 +119,14 @@ static void uds_release(struct transport *t)
free(uds);
}
+struct address *uds_default_addr(struct transport *t,
+ int event, int peer)
+{
+ struct uds *uds = container_of(t, struct uds, t);
+
+ return &uds->address;
+}
+
struct transport *uds_transport_create(void)
{
struct uds *uds;
@@ -127,6 +138,7 @@ struct transport *uds_transport_create(void)
uds->t.recv = uds_recv;
uds->t.send = uds_send;
uds->t.release = uds_release;
+ uds->t.default_addr = uds_default_addr;
return &uds->t;
}
diff --git a/util.c b/util.c
index 56af8efcb0fa..1e86040c61f7 100644
--- a/util.c
+++ b/util.c
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
+#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;
}
--
1.7.6.5