diff --git a/msg.c b/msg.c index eefd359..5c1adb0 100644 --- a/msg.c +++ b/msg.c @@ -17,6 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include +#include #include #include #include @@ -90,7 +91,7 @@ int64_t net2host64(int64_t val) static int hdr_post_recv(struct ptp_header *m) { if ((m->ver & VERSION_MASK) != VERSION) - return -1; + return -EPROTO; m->messageLength = ntohs(m->messageLength); m->correction = net2host64(m->correction); m->sourcePortIdentity.portNumber = ntohs(m->sourcePortIdentity.portNumber); @@ -107,33 +108,6 @@ static int hdr_pre_send(struct ptp_header *m) return 0; } -static char *msg_type_string(int type) -{ - switch (type) { - case SYNC: - return "SYNC"; - case DELAY_REQ: - return "DELAY_REQ"; - case PDELAY_REQ: - return "PDELAY_REQ"; - case PDELAY_RESP: - return "PDELAY_RESP"; - case FOLLOW_UP: - return "FOLLOW_UP"; - case DELAY_RESP: - return "DELAY_RESP"; - case PDELAY_RESP_FOLLOW_UP: - return "PDELAY_RESP_FOLLOW_UP"; - case ANNOUNCE: - return "ANNOUNCE"; - case SIGNALING: - return "SIGNALING"; - case MANAGEMENT: - return "MANAGEMENT"; - } - return "unknown"; -} - static void port_id_post_recv(struct PortIdentity *pid) { pid->portNumber = ntohs(pid->portNumber); @@ -146,7 +120,7 @@ static void port_id_pre_send(struct PortIdentity *pid) static int suffix_post_recv(uint8_t *ptr, int len, struct tlv_extra *last) { - int cnt; + int cnt, err; struct TLV *tlv; if (!ptr) @@ -157,18 +131,18 @@ static int suffix_post_recv(uint8_t *ptr, int len, struct tlv_extra *last) tlv->type = ntohs(tlv->type); tlv->length = ntohs(tlv->length); if (tlv->length % 2) { - return -1; + return -EBADMSG; } len -= sizeof(struct TLV); ptr += sizeof(struct TLV); if (tlv->length > len) { - return -1; + return -EBADMSG; } len -= tlv->length; ptr += tlv->length; - if (tlv_post_recv(tlv, len ? NULL : last)) { - return -1; - } + err = tlv_post_recv(tlv, len ? NULL : last); + if (err) + return err; } return cnt; } @@ -251,14 +225,15 @@ void msg_get(struct ptp_message *m) int msg_post_recv(struct ptp_message *m, int cnt) { - int pdulen, type; + int pdulen, type, err; uint8_t *suffix = NULL; if (cnt < sizeof(struct ptp_header)) - return -1; + return -EBADMSG; - if (hdr_post_recv(&m->header)) - return -1; + err = hdr_post_recv(&m->header); + if (err) + return err; type = msg_type(m); @@ -294,11 +269,11 @@ int msg_post_recv(struct ptp_message *m, int cnt) pdulen = sizeof(struct management_msg); break; default: - return -1; + return -EBADMSG; } if (cnt < pdulen) - return -1; + return -EBADMSG; switch (type) { case SYNC: @@ -339,15 +314,12 @@ int msg_post_recv(struct ptp_message *m, int cnt) break; } - if (msg_sots_missing(m)) { - pr_err("received %s without timestamp", msg_type_string(type)); - return -1; - } + if (msg_sots_missing(m)) + return -ETIME; m->tlv_count = suffix_post_recv(suffix, cnt - pdulen, &m->last_tlv); - if (m->tlv_count == -1) { - return -1; - } + if (m->tlv_count < 0) + return m->tlv_count; return 0; } @@ -405,6 +377,33 @@ int msg_pre_send(struct ptp_message *m) return 0; } +char *msg_type_string(int type) +{ + switch (type) { + case SYNC: + return "SYNC"; + case DELAY_REQ: + return "DELAY_REQ"; + case PDELAY_REQ: + return "PDELAY_REQ"; + case PDELAY_RESP: + return "PDELAY_RESP"; + case FOLLOW_UP: + return "FOLLOW_UP"; + case DELAY_RESP: + return "DELAY_RESP"; + case PDELAY_RESP_FOLLOW_UP: + return "PDELAY_RESP_FOLLOW_UP"; + case ANNOUNCE: + return "ANNOUNCE"; + case SIGNALING: + return "SIGNALING"; + case MANAGEMENT: + return "MANAGEMENT"; + } + return "unknown"; +} + void msg_print(struct ptp_message *m, FILE *fp) { fprintf(fp, diff --git a/msg.h b/msg.h index 279f3e6..1fad5e9 100644 --- a/msg.h +++ b/msg.h @@ -293,6 +293,13 @@ int msg_post_recv(struct ptp_message *m, int cnt); */ int msg_pre_send(struct ptp_message *m); +/** + * Print messages for debugging purposes. + * @param type Value of the messageType field as returned by @ref msg_type(). + * @return String describing the message type. + */ +char *msg_type_string(int type); + /** * Print messages for debugging purposes. * @param m A message obtained using @ref msg_allocate(). diff --git a/pmc_common.c b/pmc_common.c index ee88bda..6dbeaf7 100644 --- a/pmc_common.c +++ b/pmc_common.c @@ -17,6 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include @@ -163,7 +164,7 @@ int pmc_send_get_action(struct pmc *pmc, int id) struct ptp_message *pmc_recv(struct pmc *pmc) { struct ptp_message *msg; - int cnt; + int cnt, err; msg = msg_allocate(); if (!msg) { @@ -176,8 +177,20 @@ struct ptp_message *pmc_recv(struct pmc *pmc) if (cnt <= 0) { pr_err("recv message failed"); goto failed; - } else if (msg_post_recv(msg, cnt)) { - pr_err("bad message"); + } + err = msg_post_recv(msg, cnt); + if (err) { + switch (err) { + case -EBADMSG: + pr_err("bad message"); + break; + case -ETIME: + pr_err("received %s without timestamp", + msg_type_string(msg_type(msg))); + break; + case -EPROTO: + pr_debug("ignoring message"); + } goto failed; } diff --git a/port.c b/port.c index d922047..9bfbf33 100644 --- a/port.c +++ b/port.c @@ -1873,7 +1873,7 @@ enum fsm_event port_event(struct port *p, int fd_index) { enum fsm_event event = EV_NONE; struct ptp_message *msg; - int cnt, fd = p->fda.fd[fd_index]; + int cnt, fd = p->fda.fd[fd_index], err; switch (fd_index) { case FD_ANNOUNCE_TIMER: @@ -1918,8 +1918,19 @@ enum fsm_event port_event(struct port *p, int fd_index) msg_put(msg); return EV_FAULT_DETECTED; } - if (msg_post_recv(msg, cnt)) { - pr_err("port %hu: bad message", portnum(p)); + err = msg_post_recv(msg, cnt); + if (err) { + switch (err) { + case -EBADMSG: + pr_err("port %hu: bad message", portnum(p)); + break; + case -ETIME: + pr_err("port %hu: received %s without timestamp", + portnum(p), msg_type_string(msg_type(msg))); + break; + case -EPROTO: + pr_debug("port %hu: ignoring message", portnum(p)); + } msg_put(msg); return EV_NONE; } diff --git a/tlv.c b/tlv.c index 9b9e420..ce72e4b 100644 --- a/tlv.c +++ b/tlv.c @@ -17,6 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include +#include #include #include "port.h" @@ -171,7 +172,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len, } return 0; bad_length: - return -1; + return -EBADMSG; } static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra) @@ -260,7 +261,7 @@ static int org_post_recv(struct organization_tlv *org) } return 0; bad_length: - return -1; + return -EBADMSG; } static void org_pre_send(struct organization_tlv *org) @@ -335,7 +336,7 @@ int tlv_post_recv(struct TLV *tlv, struct tlv_extra *extra) } return result; bad_length: - return -1; + return -EBADMSG; } void tlv_pre_send(struct TLV *tlv, struct tlv_extra *extra)