From 362a06e37d82eae495b386f85aa5106b8dc7dffc Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 28 Mar 2018 14:35:56 +0200 Subject: [PATCH] bgpd: Flowspec display handlers uses snprintf snprintf routine is used widely, when the handler routine in charge of displaying the output is called. Signed-off-by: Philippe Guibert --- bgpd/bgp_flowspec_util.c | 108 ++++++++++++++++++++++++++++++--------- bgpd/bgp_flowspec_vty.c | 92 ++++++++++++++++++++++----------- 2 files changed, 147 insertions(+), 53 deletions(-) diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c index 7391a7b80a..007b27f17e 100644 --- a/bgpd/bgp_flowspec_util.c +++ b/bgpd/bgp_flowspec_util.c @@ -107,6 +107,8 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type, * return number of bytes analysed * if there is an error, the passed error param is used to give error: * -1 if decoding error, + * if result is a string, its assumed length + * is BGP_FLOWSPEC_STRING_DISPLAY_MAX */ int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type, uint8_t *nlri_ptr, @@ -118,6 +120,8 @@ int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type, int loop = 0; char *ptr = (char *)result; /* for return_string */ uint32_t offset = 0; + int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX; + int len_written; *error = 0; do { @@ -134,15 +138,34 @@ int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type, *error = -1; switch (type) { case BGP_FLOWSPEC_RETURN_STRING: - if (loop) - ptr += sprintf(ptr, ", "); - if (op[5] == 1) - ptr += sprintf(ptr, "<"); - if (op[6] == 1) - ptr += sprintf(ptr, ">"); - if (op[7] == 1) - ptr += sprintf(ptr, "="); - ptr += sprintf(ptr, " %d ", value); + if (loop) { + len_written = snprintf(ptr, len_string, + ", "); + len_string -= len_written; + ptr += len_written; + } + if (op[5] == 1) { + len_written = snprintf(ptr, len_string, + "<"); + len_string -= len_written; + ptr += len_written; + } + if (op[6] == 1) { + len_written = snprintf(ptr, len_string, + ">"); + len_string -= len_written; + ptr += len_written; + } + if (op[7] == 1) { + len_written = snprintf(ptr, len_string, + "="); + len_string -= len_written; + ptr += len_written; + } + len_written = snprintf(ptr, len_string, + " %d ", value); + len_string -= len_written; + ptr += len_written; break; case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE: /* TODO : FS OPAQUE */ @@ -169,6 +192,8 @@ int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type, * return number of bytes analysed * if there is an error, the passed error param is used to give error: * -1 if decoding error, + * if result is a string, its assumed length + * is BGP_FLOWSPEC_STRING_DISPLAY_MAX */ int bgp_flowspec_tcpflags_decode(enum bgp_flowspec_util_nlri_t type, uint8_t *nlri_ptr, @@ -179,6 +204,8 @@ int bgp_flowspec_tcpflags_decode(enum bgp_flowspec_util_nlri_t type, int len, value_size, loop = 0, value; char *ptr = (char *)result; /* for return_string */ uint32_t offset = 0; + int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX; + int len_written; *error = 0; do { @@ -192,16 +219,37 @@ int bgp_flowspec_tcpflags_decode(enum bgp_flowspec_util_nlri_t type, value = hexstr2num(&nlri_ptr[offset], value_size); switch (type) { case BGP_FLOWSPEC_RETURN_STRING: - if (op[1] == 1 && loop != 0) - ptr += sprintf(ptr, ", and "); - else if (op[1] == 0 && loop != 0) - ptr += sprintf(ptr, ", or "); - ptr += sprintf(ptr, "tcp flags is "); - if (op[6] == 1) - ptr += sprintf(ptr, "not "); - if (op[7] == 1) - ptr += sprintf(ptr, "exactly match "); - ptr += sprintf(ptr, "%d", value); + if (op[1] == 1 && loop != 0) { + len_written = snprintf(ptr, len_string, + ", and "); + len_string -= len_written; + ptr += len_written; + } else if (op[1] == 0 && loop != 0) { + len_written = snprintf(ptr, len_string, + ", or "); + len_string -= len_written; + ptr += len_written; + } + len_written = snprintf(ptr, len_string, + "tcp flags is "); + len_string -= len_written; + ptr += len_written; + if (op[6] == 1) { + ptr += snprintf(ptr, len_string, + "not "); + len_string -= len_written; + ptr += len_written; + } + if (op[7] == 1) { + ptr += snprintf(ptr, len_string, + "exactly match "); + len_string -= len_written; + ptr += len_written; + } + ptr += snprintf(ptr, len_string, + "%d", value); + len_string -= len_written; + ptr += len_written; break; case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE: /* TODO : FS OPAQUE */ @@ -237,6 +285,8 @@ int bgp_flowspec_fragment_type_decode(enum bgp_flowspec_util_nlri_t type, int len, value, value_size, loop = 0; char *ptr = (char *)result; /* for return_string */ uint32_t offset = 0; + int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX; + int len_written; *error = 0; do { @@ -262,16 +312,28 @@ int bgp_flowspec_fragment_type_decode(enum bgp_flowspec_util_nlri_t type, case BGP_FLOWSPEC_RETURN_STRING: switch (value) { case 1: - ptr += sprintf(ptr, "dont-fragment"); + len_written = snprintf(ptr, len_string, + "dont-fragment"); + len_string -= len_written; + ptr += len_written; break; case 2: - ptr += sprintf(ptr, "is-fragment"); + len_written = snprintf(ptr, len_string, + "is-fragment"); + len_string -= len_written; + ptr += len_written; break; case 4: - ptr += sprintf(ptr, "first-fragment"); + len_written = snprintf(ptr, len_string, + "first-fragment"); + len_string -= len_written; + ptr += len_written; break; case 8: - ptr += sprintf(ptr, "last-fragment"); + len_written = snprintf(ptr, len_string, + "last-fragment"); + len_string -= len_written; + ptr += len_written; break; default: {} diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index eae9bedcbd..247da5d183 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -68,16 +68,28 @@ static const struct message bgp_flowspec_display_min[] = { {0} }; -#define FS_STRING_UPDATE(count, ptr, format) do { \ - if (((format) == NLRI_STRING_FORMAT_DEBUG) && (count)) { \ - (ptr) += sprintf((ptr), ", "); \ - } else if (((format) == NLRI_STRING_FORMAT_MIN) && (count)) { \ - (ptr) += sprintf((ptr), " "); \ - } \ - count++; \ +#define FS_STRING_UPDATE(count, ptr, format, remaining_len) do { \ + int _len_written; \ + \ + if (((format) == NLRI_STRING_FORMAT_DEBUG) && (count)) {\ + _len_written = snprintf((ptr), (remaining_len), \ + ", "); \ + (remaining_len) -= _len_written; \ + (ptr) += _len_written; \ + } else if (((format) == NLRI_STRING_FORMAT_MIN) \ + && (count)) { \ + _len_written = snprintf((ptr), (remaining_len), \ + " "); \ + (remaining_len) -= _len_written; \ + (ptr) += _len_written; \ + } \ + count++; \ } while (0) -/* Parse FLOWSPEC NLRI*/ +/* Parse FLOWSPEC NLRI + * passed return_string string has assumed length + * BGP_FLOWSPEC_STRING_DISPLAY_MAX + */ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len, char *return_string, int format, json_object *json_path) @@ -92,6 +104,8 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len, char pre_extra[2] = ""; const struct message *bgp_flowspec_display; enum bgp_flowspec_util_nlri_t type_util; + int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX; + int len_written; if (format == NLRI_STRING_FORMAT_LARGE) { snprintf(pre_extra, sizeof(pre_extra), "\t"); @@ -121,10 +135,14 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len, local_string); break; } - FS_STRING_UPDATE(count, ptr, format); - ptr += sprintf(ptr, "%s%s %s%s", pre_extra, - lookup_msg(bgp_flowspec_display, type, ""), - local_string, extra); + FS_STRING_UPDATE(count, ptr, format, len_string); + len_written = snprintf(ptr, len_string, "%s%s %s%s", + pre_extra, + lookup_msg(bgp_flowspec_display, + type, ""), + local_string, extra); + len_string -= len_written; + ptr += len_written; break; case FLOWSPEC_IP_PROTOCOL: case FLOWSPEC_PORT: @@ -144,11 +162,14 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len, local_string); break; } - FS_STRING_UPDATE(count, ptr, format); - ptr += sprintf(ptr, "%s%s %s%s", pre_extra, - lookup_msg(bgp_flowspec_display, - type, ""), + FS_STRING_UPDATE(count, ptr, format, len_string); + len_written = snprintf(ptr, len_string, "%s%s %s%s", + pre_extra, + lookup_msg(bgp_flowspec_display, + type, ""), local_string, extra); + len_string -= len_written; + ptr += len_written; break; case FLOWSPEC_TCP_FLAGS: ret = bgp_flowspec_tcpflags_decode( @@ -160,14 +181,19 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len, break; if (json_path) { json_object_string_add(json_path, - lookup_msg(bgp_flowspec_display, type, ""), + lookup_msg(bgp_flowspec_display, + type, ""), local_string); break; } - FS_STRING_UPDATE(count, ptr, format); - ptr += sprintf(ptr, "%s%s %s%s", pre_extra, - lookup_msg(bgp_flowspec_display, type, ""), - local_string, extra); + FS_STRING_UPDATE(count, ptr, format, len_string); + len_written = snprintf(ptr, len_string, "%s%s %s%s", + pre_extra, + lookup_msg(bgp_flowspec_display, + type, ""), + local_string, extra); + len_string -= len_written; + ptr += len_written; break; case FLOWSPEC_PKT_LEN: case FLOWSPEC_DSCP: @@ -184,11 +210,14 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len, local_string); break; } - FS_STRING_UPDATE(count, ptr, format); - ptr += sprintf(ptr, "%s%s %s%s", pre_extra, - lookup_msg(bgp_flowspec_display, - type, ""), + FS_STRING_UPDATE(count, ptr, format, len_string); + len_written = snprintf(ptr, len_string, "%s%s %s%s", + pre_extra, + lookup_msg(bgp_flowspec_display, + type, ""), local_string, extra); + len_string -= len_written; + ptr += len_written; break; case FLOWSPEC_FRAGMENT: ret = bgp_flowspec_fragment_type_decode( @@ -205,11 +234,14 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len, local_string); break; } - FS_STRING_UPDATE(count, ptr, format); - ptr += sprintf(ptr, "%s%s %s%s", pre_extra, - lookup_msg(bgp_flowspec_display, - type, ""), - local_string, extra); + FS_STRING_UPDATE(count, ptr, format, len_string); + len_written = snprintf(ptr, len_string, "%s%s %s%s", + pre_extra, + lookup_msg(bgp_flowspec_display, + type, ""), + local_string, extra); + len_string -= len_written; + ptr += len_written; break; default: error = -1;