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
parent
5d7e1b0f18
commit
0367bb5f1b
93
msg.c
93
msg.c
|
@ -17,6 +17,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -90,7 +91,7 @@ int64_t net2host64(int64_t val)
|
||||||
static int hdr_post_recv(struct ptp_header *m)
|
static int hdr_post_recv(struct ptp_header *m)
|
||||||
{
|
{
|
||||||
if ((m->ver & VERSION_MASK) != VERSION)
|
if ((m->ver & VERSION_MASK) != VERSION)
|
||||||
return -1;
|
return -EPROTO;
|
||||||
m->messageLength = ntohs(m->messageLength);
|
m->messageLength = ntohs(m->messageLength);
|
||||||
m->correction = net2host64(m->correction);
|
m->correction = net2host64(m->correction);
|
||||||
m->sourcePortIdentity.portNumber = ntohs(m->sourcePortIdentity.portNumber);
|
m->sourcePortIdentity.portNumber = ntohs(m->sourcePortIdentity.portNumber);
|
||||||
|
@ -107,33 +108,6 @@ static int hdr_pre_send(struct ptp_header *m)
|
||||||
return 0;
|
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)
|
static void port_id_post_recv(struct PortIdentity *pid)
|
||||||
{
|
{
|
||||||
pid->portNumber = ntohs(pid->portNumber);
|
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)
|
static int suffix_post_recv(uint8_t *ptr, int len, struct tlv_extra *last)
|
||||||
{
|
{
|
||||||
int cnt;
|
int cnt, err;
|
||||||
struct TLV *tlv;
|
struct TLV *tlv;
|
||||||
|
|
||||||
if (!ptr)
|
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->type = ntohs(tlv->type);
|
||||||
tlv->length = ntohs(tlv->length);
|
tlv->length = ntohs(tlv->length);
|
||||||
if (tlv->length % 2) {
|
if (tlv->length % 2) {
|
||||||
return -1;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
len -= sizeof(struct TLV);
|
len -= sizeof(struct TLV);
|
||||||
ptr += sizeof(struct TLV);
|
ptr += sizeof(struct TLV);
|
||||||
if (tlv->length > len) {
|
if (tlv->length > len) {
|
||||||
return -1;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
len -= tlv->length;
|
len -= tlv->length;
|
||||||
ptr += tlv->length;
|
ptr += tlv->length;
|
||||||
if (tlv_post_recv(tlv, len ? NULL : last)) {
|
err = tlv_post_recv(tlv, len ? NULL : last);
|
||||||
return -1;
|
if (err)
|
||||||
}
|
return err;
|
||||||
}
|
}
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
@ -251,14 +225,15 @@ void msg_get(struct ptp_message *m)
|
||||||
|
|
||||||
int msg_post_recv(struct ptp_message *m, int cnt)
|
int msg_post_recv(struct ptp_message *m, int cnt)
|
||||||
{
|
{
|
||||||
int pdulen, type;
|
int pdulen, type, err;
|
||||||
uint8_t *suffix = NULL;
|
uint8_t *suffix = NULL;
|
||||||
|
|
||||||
if (cnt < sizeof(struct ptp_header))
|
if (cnt < sizeof(struct ptp_header))
|
||||||
return -1;
|
return -EBADMSG;
|
||||||
|
|
||||||
if (hdr_post_recv(&m->header))
|
err = hdr_post_recv(&m->header);
|
||||||
return -1;
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
type = msg_type(m);
|
type = msg_type(m);
|
||||||
|
|
||||||
|
@ -294,11 +269,11 @@ int msg_post_recv(struct ptp_message *m, int cnt)
|
||||||
pdulen = sizeof(struct management_msg);
|
pdulen = sizeof(struct management_msg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cnt < pdulen)
|
if (cnt < pdulen)
|
||||||
return -1;
|
return -EBADMSG;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SYNC:
|
case SYNC:
|
||||||
|
@ -339,15 +314,12 @@ int msg_post_recv(struct ptp_message *m, int cnt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg_sots_missing(m)) {
|
if (msg_sots_missing(m))
|
||||||
pr_err("received %s without timestamp", msg_type_string(type));
|
return -ETIME;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m->tlv_count = suffix_post_recv(suffix, cnt - pdulen, &m->last_tlv);
|
m->tlv_count = suffix_post_recv(suffix, cnt - pdulen, &m->last_tlv);
|
||||||
if (m->tlv_count == -1) {
|
if (m->tlv_count < 0)
|
||||||
return -1;
|
return m->tlv_count;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -405,6 +377,33 @@ int msg_pre_send(struct ptp_message *m)
|
||||||
return 0;
|
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)
|
void msg_print(struct ptp_message *m, FILE *fp)
|
||||||
{
|
{
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
|
|
7
msg.h
7
msg.h
|
@ -293,6 +293,13 @@ int msg_post_recv(struct ptp_message *m, int cnt);
|
||||||
*/
|
*/
|
||||||
int msg_pre_send(struct ptp_message *m);
|
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.
|
* Print messages for debugging purposes.
|
||||||
* @param m A message obtained using @ref msg_allocate().
|
* @param m A message obtained using @ref msg_allocate().
|
||||||
|
|
17
pmc_common.c
17
pmc_common.c
|
@ -17,6 +17,7 @@
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.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 *pmc_recv(struct pmc *pmc)
|
||||||
{
|
{
|
||||||
struct ptp_message *msg;
|
struct ptp_message *msg;
|
||||||
int cnt;
|
int cnt, err;
|
||||||
|
|
||||||
msg = msg_allocate();
|
msg = msg_allocate();
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
|
@ -176,8 +177,20 @@ struct ptp_message *pmc_recv(struct pmc *pmc)
|
||||||
if (cnt <= 0) {
|
if (cnt <= 0) {
|
||||||
pr_err("recv message failed");
|
pr_err("recv message failed");
|
||||||
goto 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");
|
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;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
port.c
15
port.c
|
@ -1873,7 +1873,7 @@ enum fsm_event port_event(struct port *p, int fd_index)
|
||||||
{
|
{
|
||||||
enum fsm_event event = EV_NONE;
|
enum fsm_event event = EV_NONE;
|
||||||
struct ptp_message *msg;
|
struct ptp_message *msg;
|
||||||
int cnt, fd = p->fda.fd[fd_index];
|
int cnt, fd = p->fda.fd[fd_index], err;
|
||||||
|
|
||||||
switch (fd_index) {
|
switch (fd_index) {
|
||||||
case FD_ANNOUNCE_TIMER:
|
case FD_ANNOUNCE_TIMER:
|
||||||
|
@ -1918,8 +1918,19 @@ enum fsm_event port_event(struct port *p, int fd_index)
|
||||||
msg_put(msg);
|
msg_put(msg);
|
||||||
return EV_FAULT_DETECTED;
|
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));
|
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);
|
msg_put(msg);
|
||||||
return EV_NONE;
|
return EV_NONE;
|
||||||
}
|
}
|
||||||
|
|
7
tlv.c
7
tlv.c
|
@ -17,6 +17,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
|
@ -171,7 +172,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
bad_length:
|
bad_length:
|
||||||
return -1;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra)
|
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;
|
return 0;
|
||||||
bad_length:
|
bad_length:
|
||||||
return -1;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void org_pre_send(struct organization_tlv *org)
|
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;
|
return result;
|
||||||
bad_length:
|
bad_length:
|
||||||
return -1;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tlv_pre_send(struct TLV *tlv, struct tlv_extra *extra)
|
void tlv_pre_send(struct TLV *tlv, struct tlv_extra *extra)
|
||||||
|
|
Loading…
Reference in New Issue