Distinguish between ignored and malformed packets

When there is a peer speaking PTPv1 in the network we want to silently ignore
the packets instead of flooding system log with error messages.  At the same
time we still want to report malformed packets.  For that we reuse standard
error numbers and do more fine-grained error reporting in packet processing
routines.

Signed-off-by: Libor Pechacek <lpechacek@suse.cz>
master
Libor Pechacek 2013-03-28 16:30:17 +01:00 committed by Richard Cochran
parent 5d7e1b0f18
commit 0367bb5f1b
5 changed files with 87 additions and 56 deletions

93
msg.c
View File

@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <arpa/inet.h>
#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <time.h>
@ -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,

7
msg.h
View File

@ -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().

View File

@ -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 <errno.h>
#include <string.h>
#include <stdlib.h>
@ -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)) {
}
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;
}

15
port.c
View File

@ -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)) {
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;
}

7
tlv.c
View File

@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#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)