lib: make sprint_canframe the buffer size aware snprintf_canframe
Make sure the library functions to convert CAN frames into ASCII represenation do not exceed the given buffer size. This also applies to the long CAN frame output library function. Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>pull/504/head
parent
8e131401c1
commit
27030b3e54
|
|
@ -82,7 +82,7 @@ void prframe(FILE *file, struct timeval *tv, int dev, struct canfd_frame *cf, ch
|
||||||
else
|
else
|
||||||
fprintf(file, "canX ");
|
fprintf(file, "canX ");
|
||||||
|
|
||||||
sprint_canframe(abuf, (cu_t *)cf, 0);
|
snprintf_canframe(abuf, sizeof(abuf), (cu_t *)cf, 0);
|
||||||
fprintf(file, "%s%s", abuf, extra_info);
|
fprintf(file, "%s%s", abuf, extra_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -837,7 +837,7 @@ int main(int argc, char **argv)
|
||||||
alen += sprintf(afrbuf + alen, "%*s ",
|
alen += sprintf(afrbuf + alen, "%*s ",
|
||||||
max_devname_len, devname[idx]);
|
max_devname_len, devname[idx]);
|
||||||
|
|
||||||
alen += sprint_canframe(afrbuf + alen, &cu, 0);
|
alen += snprintf_canframe(afrbuf + alen, sizeof(afrbuf) - alen, &cu, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write CAN frame in log file style to logfile */
|
/* write CAN frame in log file style to logfile */
|
||||||
|
|
@ -876,7 +876,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
alen += sprintf(afrbuf + alen, "%s ", (color == 1) ? col_off : "");
|
alen += sprintf(afrbuf + alen, "%s ", (color == 1) ? col_off : "");
|
||||||
alen += sprint_long_canframe(afrbuf + alen, &cu, view);
|
alen += snprintf_long_canframe(afrbuf + alen, sizeof(afrbuf) - alen, &cu, view);
|
||||||
|
|
||||||
if ((view & CANLIB_VIEW_ERROR) && (cu.fd.can_id & CAN_ERR_FLAG)) {
|
if ((view & CANLIB_VIEW_ERROR) && (cu.fd.can_id & CAN_ERR_FLAG)) {
|
||||||
alen += sprintf(afrbuf + alen, "\n\t");
|
alen += sprintf(afrbuf + alen, "\n\t");
|
||||||
|
|
|
||||||
4
cangen.c
4
cangen.c
|
|
@ -1009,9 +1009,9 @@ int main(int argc, char **argv)
|
||||||
printf(" %s ", argv[optind]);
|
printf(" %s ", argv[optind]);
|
||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
sprint_long_canframe(afrbuf, &cu, view);
|
snprintf_long_canframe(afrbuf, sizeof(afrbuf), &cu, view);
|
||||||
else
|
else
|
||||||
sprint_canframe(afrbuf, &cu, 1);
|
snprintf_canframe(afrbuf, sizeof(afrbuf), &cu, 1);
|
||||||
|
|
||||||
printf("%s\n", afrbuf);
|
printf("%s\n", afrbuf);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -439,7 +439,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
sprintf(afrbuf, "(%llu.%06llu) %*s ",
|
sprintf(afrbuf, "(%llu.%06llu) %*s ",
|
||||||
(unsigned long long)tv.tv_sec, (unsigned long long)tv.tv_usec, max_devname_len, devname[idx]);
|
(unsigned long long)tv.tv_sec, (unsigned long long)tv.tv_usec, max_devname_len, devname[idx]);
|
||||||
sprint_canframe(afrbuf+strlen(afrbuf), &cu, 0);
|
snprintf_canframe(afrbuf + strlen(afrbuf), sizeof(afrbuf) - strlen(afrbuf), &cu, 0);
|
||||||
strcat(afrbuf, "\n");
|
strcat(afrbuf, "\n");
|
||||||
|
|
||||||
if (write(accsocket, afrbuf, strlen(afrbuf)) < 0) {
|
if (write(accsocket, afrbuf, strlen(afrbuf)) < 0) {
|
||||||
|
|
|
||||||
|
|
@ -513,7 +513,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("%s (%s) ", get_txname(device), device);
|
printf("%s (%s) ", get_txname(device), device);
|
||||||
sprint_long_canframe(afrbuf, &cu, CANLIB_VIEW_INDENT_SFF);
|
snprintf_long_canframe(afrbuf, sizeof(afrbuf), &cu, CANLIB_VIEW_INDENT_SFF);
|
||||||
printf("%s\n", afrbuf);
|
printf("%s\n", afrbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
100
lib.c
100
lib.c
|
|
@ -308,7 +308,7 @@ int parse_canframe(char *cs, cu_t *cu)
|
||||||
return mtu;
|
return mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sprint_canframe(char *buf, cu_t *cu, int sep)
|
int snprintf_canframe(char *buf, size_t size, cu_t *cu, int sep)
|
||||||
{
|
{
|
||||||
/* documentation see lib.h */
|
/* documentation see lib.h */
|
||||||
|
|
||||||
|
|
@ -316,10 +316,22 @@ int sprint_canframe(char *buf, cu_t *cu, int sep)
|
||||||
int i, offset;
|
int i, offset;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
/* ensure space for string termination */
|
||||||
|
if (size < 1)
|
||||||
|
return size;
|
||||||
|
|
||||||
/* handle CAN XL frames */
|
/* handle CAN XL frames */
|
||||||
if (cu->xl.flags & CANXL_XLF) {
|
if (cu->xl.flags & CANXL_XLF) {
|
||||||
len = cu->xl.len;
|
len = cu->xl.len;
|
||||||
|
|
||||||
|
/* check if the CAN frame fits into the provided buffer */
|
||||||
|
if (sizeof("00123#11:22:12345678#") + 2 * len + (sep ? len : 0) > size - 1) {
|
||||||
|
/* mark buffer overflow in output */
|
||||||
|
memset(buf, '-', size - 1);
|
||||||
|
buf[size - 1] = 0;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
/* print prio and CAN XL header content */
|
/* print prio and CAN XL header content */
|
||||||
offset = sprintf(buf, "%02X%03X#%02X:%02X:%08X#",
|
offset = sprintf(buf, "%02X%03X#%02X:%02X:%08X#",
|
||||||
(canid_t)(cu->xl.prio & CANXL_VCID_MASK) >> CANXL_VCID_OFFSET,
|
(canid_t)(cu->xl.prio & CANXL_VCID_MASK) >> CANXL_VCID_OFFSET,
|
||||||
|
|
@ -345,6 +357,15 @@ int sprint_canframe(char *buf, cu_t *cu, int sep)
|
||||||
else
|
else
|
||||||
len = (cu->fd.len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cu->fd.len;
|
len = (cu->fd.len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cu->fd.len;
|
||||||
|
|
||||||
|
/* check if the CAN frame fits into the provided buffer */
|
||||||
|
if (sizeof("12345678#_F") + 2 * len + (sep ? len : 0) + \
|
||||||
|
(cu->fd.can_id & CAN_RTR_FLAG ? 2 : 0) > size - 1) {
|
||||||
|
/* mark buffer overflow in output */
|
||||||
|
memset(buf, '-', size - 1);
|
||||||
|
buf[size - 1] = 0;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
if (cu->fd.can_id & CAN_ERR_FLAG) {
|
if (cu->fd.can_id & CAN_ERR_FLAG) {
|
||||||
put_eff_id(buf, cu->fd.can_id & (CAN_ERR_MASK | CAN_ERR_FLAG));
|
put_eff_id(buf, cu->fd.can_id & (CAN_ERR_MASK | CAN_ERR_FLAG));
|
||||||
buf[8] = '#';
|
buf[8] = '#';
|
||||||
|
|
@ -411,48 +432,60 @@ int sprint_canframe(char *buf, cu_t *cu, int sep)
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sprint_long_canframe(char *buf, cu_t *cu, int view)
|
int snprintf_long_canframe(char *buf, size_t size, cu_t *cu, int view)
|
||||||
{
|
{
|
||||||
/* documentation see lib.h */
|
/* documentation see lib.h */
|
||||||
|
|
||||||
unsigned char is_canfd = cu->fd.flags;
|
unsigned char is_canfd = cu->fd.flags;
|
||||||
int i, j, dlen, offset;
|
int i, j, dlen, offset, maxsize;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
/* initialize space for CAN-ID and length information */
|
/* ensure space for string termination */
|
||||||
memset(buf, ' ', 15);
|
if (size < 1)
|
||||||
|
return size;
|
||||||
|
|
||||||
/* handle CAN XL frames */
|
/* handle CAN XL frames */
|
||||||
if (cu->xl.flags & CANXL_XLF) {
|
if (cu->xl.flags & CANXL_XLF) {
|
||||||
len = cu->xl.len;
|
len = cu->xl.len;
|
||||||
|
|
||||||
|
/* crop to CANFD_MAX_DLEN */
|
||||||
|
if (len > CANFD_MAX_DLEN)
|
||||||
|
dlen = CANFD_MAX_DLEN;
|
||||||
|
else
|
||||||
|
dlen = len;
|
||||||
|
|
||||||
|
/* check if the CAN frame fits into the provided buffer */
|
||||||
|
if (sizeof(".....123 [2048] (00|11:22:12345678) ...") + 3 * dlen > size - 1) {
|
||||||
|
/* mark buffer overflow in output */
|
||||||
|
memset(buf, '-', size - 1);
|
||||||
|
buf[size - 1] = 0;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
if (view & CANLIB_VIEW_INDENT_SFF) {
|
if (view & CANLIB_VIEW_INDENT_SFF) {
|
||||||
|
memset(buf, ' ', 5);
|
||||||
put_sff_id(buf + 5, cu->xl.prio & CANXL_PRIO_MASK);
|
put_sff_id(buf + 5, cu->xl.prio & CANXL_PRIO_MASK);
|
||||||
offset = 9;
|
offset = 8;
|
||||||
} else {
|
} else {
|
||||||
put_sff_id(buf, cu->xl.prio & CANXL_PRIO_MASK);
|
put_sff_id(buf, cu->xl.prio & CANXL_PRIO_MASK);
|
||||||
offset = 4;
|
offset = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print prio and CAN XL header content */
|
/* print prio and CAN XL header content */
|
||||||
offset += sprintf(buf + offset, "[%04d] (%02X|%02X:%02X:%08X) ",
|
offset += sprintf(buf + offset, " [%04d] (%02X|%02X:%02X:%08X) ",
|
||||||
len,
|
len,
|
||||||
(canid_t)(cu->xl.prio & CANXL_VCID_MASK) >> CANXL_VCID_OFFSET,
|
(canid_t)(cu->xl.prio & CANXL_VCID_MASK) >> CANXL_VCID_OFFSET,
|
||||||
cu->xl.flags, cu->xl.sdt, cu->xl.af);
|
cu->xl.flags, cu->xl.sdt, cu->xl.af);
|
||||||
|
|
||||||
/* data - crop to CANFD_MAX_DLEN */
|
for (i = 0; i < dlen; i++) {
|
||||||
if (len > CANFD_MAX_DLEN)
|
|
||||||
len = CANFD_MAX_DLEN;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
put_hex_byte(buf + offset, cu->xl.data[i]);
|
put_hex_byte(buf + offset, cu->xl.data[i]);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
if (i + 1 < len)
|
if (i + 1 < dlen)
|
||||||
buf[offset++] = ' ';
|
buf[offset++] = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* indicate cropped output */
|
/* indicate cropped output */
|
||||||
if (cu->xl.len > len)
|
if (cu->xl.len > dlen)
|
||||||
offset += sprintf(buf + offset, " ...");
|
offset += sprintf(buf + offset, " ...");
|
||||||
|
|
||||||
buf[offset] = 0;
|
buf[offset] = 0;
|
||||||
|
|
@ -466,6 +499,39 @@ int sprint_long_canframe(char *buf, cu_t *cu, int view)
|
||||||
else
|
else
|
||||||
len = (cu->fd.len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cu->fd.len;
|
len = (cu->fd.len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cu->fd.len;
|
||||||
|
|
||||||
|
/* check if the CAN frame fits into the provided buffer */
|
||||||
|
maxsize = sizeof("12345678 [12] ");
|
||||||
|
if (view & CANLIB_VIEW_BINARY)
|
||||||
|
dlen = 9; /* _10101010 */
|
||||||
|
else
|
||||||
|
dlen = 3; /* _AA */
|
||||||
|
|
||||||
|
if (cu->fd.can_id & CAN_RTR_FLAG) {
|
||||||
|
maxsize += sizeof(" remote request");
|
||||||
|
} else {
|
||||||
|
maxsize += len * dlen;
|
||||||
|
|
||||||
|
if (len <= CAN_MAX_DLEN) {
|
||||||
|
if (cu->fd.can_id & CAN_ERR_FLAG) {
|
||||||
|
maxsize += sizeof(" ERRORFRAME");
|
||||||
|
maxsize += (8 - len) * dlen;
|
||||||
|
} else if (view & CANLIB_VIEW_ASCII) {
|
||||||
|
maxsize += sizeof(" 'a.b.CDEF'");
|
||||||
|
maxsize += (8 - len) * dlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxsize > size - 1) {
|
||||||
|
/* mark buffer overflow in output */
|
||||||
|
memset(buf, '-', size - 1);
|
||||||
|
buf[size - 1] = 0;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize space for CAN-ID and length information */
|
||||||
|
memset(buf, ' ', 15);
|
||||||
|
|
||||||
if (cu->cc.can_id & CAN_ERR_FLAG) {
|
if (cu->cc.can_id & CAN_ERR_FLAG) {
|
||||||
put_eff_id(buf, cu->cc.can_id & (CAN_ERR_MASK | CAN_ERR_FLAG));
|
put_eff_id(buf, cu->cc.can_id & (CAN_ERR_MASK | CAN_ERR_FLAG));
|
||||||
offset = 10;
|
offset = 10;
|
||||||
|
|
@ -515,7 +581,7 @@ int sprint_long_canframe(char *buf, cu_t *cu, int view)
|
||||||
offset += 5;
|
offset += 5;
|
||||||
|
|
||||||
if (view & CANLIB_VIEW_BINARY) {
|
if (view & CANLIB_VIEW_BINARY) {
|
||||||
dlen = 9; /* _10101010 */
|
/* _10101010 - dlen = 9, see above */
|
||||||
if (view & CANLIB_VIEW_SWAP) {
|
if (view & CANLIB_VIEW_SWAP) {
|
||||||
for (i = len - 1; i >= 0; i--) {
|
for (i = len - 1; i >= 0; i--) {
|
||||||
buf[offset++] = (i == len - 1) ? ' ' : SWAP_DELIMITER;
|
buf[offset++] = (i == len - 1) ? ' ' : SWAP_DELIMITER;
|
||||||
|
|
@ -530,7 +596,7 @@ int sprint_long_canframe(char *buf, cu_t *cu, int view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dlen = 3; /* _AA */
|
/* _AA - dlen = 3, see above */
|
||||||
if (view & CANLIB_VIEW_SWAP) {
|
if (view & CANLIB_VIEW_SWAP) {
|
||||||
for (i = len - 1; i >= 0; i--) {
|
for (i = len - 1; i >= 0; i--) {
|
||||||
if (i == len - 1)
|
if (i == len - 1)
|
||||||
|
|
|
||||||
4
lib.h
4
lib.h
|
|
@ -178,7 +178,7 @@ int parse_canframe(char *cs, cu_t *cu);
|
||||||
* - CAN FD frames do not have a RTR bit
|
* - CAN FD frames do not have a RTR bit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int sprint_canframe(char *buf , cu_t *cu, int sep);
|
int snprintf_canframe(char *buf, size_t size, cu_t *cu, int sep);
|
||||||
/*
|
/*
|
||||||
* Creates a CAN frame hexadecimal output in compact format.
|
* Creates a CAN frame hexadecimal output in compact format.
|
||||||
* The CAN data[] is separated by '.' when sep != 0.
|
* The CAN data[] is separated by '.' when sep != 0.
|
||||||
|
|
@ -211,7 +211,7 @@ int sprint_canframe(char *buf , cu_t *cu, int sep);
|
||||||
|
|
||||||
#define SWAP_DELIMITER '`'
|
#define SWAP_DELIMITER '`'
|
||||||
|
|
||||||
int sprint_long_canframe(char *buf , cu_t *cu, int view);
|
int snprintf_long_canframe(char *buf, size_t size, cu_t *cu, int view);
|
||||||
/*
|
/*
|
||||||
* Creates a CAN frame hexadecimal output in user readable format.
|
* Creates a CAN frame hexadecimal output in user readable format.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,8 @@ int main(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* with ASCII output */
|
/* with ASCII output */
|
||||||
sprint_long_canframe(afrbuf, &cu,
|
snprintf_long_canframe(afrbuf, sizeof(afrbuf), &cu,
|
||||||
(CANLIB_VIEW_INDENT_SFF | CANLIB_VIEW_ASCII));
|
(CANLIB_VIEW_INDENT_SFF | CANLIB_VIEW_ASCII));
|
||||||
|
|
||||||
printf("%s %s %s\n", timestamp, device, afrbuf);
|
printf("%s %s %s\n", timestamp, device, afrbuf);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue