ipproto_name() returns a static string of theoretically unbounded length.
That's going to be inconvenient in future, so introduce IPPROTO_STRLEN
giving an explicit bound on the length. Use static_assert() and some
macros to ensure nothing we return can exceed this.
Signed-off-by: David Gibson
---
ip.c | 18 ++++++++++++------
ip.h | 2 ++
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/ip.c b/ip.c
index 0ea62998..25fa4073 100644
--- a/ip.c
+++ b/ip.c
@@ -12,6 +12,7 @@
* Author: Stefano Brivio
*/
+#include
#include
#include
@@ -74,7 +75,7 @@ found:
* ipproto_name() - Get IP protocol name from number
* @proto: IP protocol number
*
- * Return: pointer to name of protocol @proto
+ * Return: pointer to name of protocol @proto (<= IPPROTO_STRLEN bytes)
*
* Usually this would be done with getprotobynumber(3) but that reads
* /etc/protocols and might allocate, which isn't possible for us once
@@ -83,16 +84,21 @@ found:
const char *ipproto_name(uint8_t proto)
{
switch (proto) {
+#define CASE(s) \
+ static_assert(sizeof(s) <= IPPROTO_STRLEN, \
+ "Increase IPPROTO_STRLEN to contain " #s); \
+ return s;
case IPPROTO_ICMP:
- return "ICMP";
+ CASE("ICMP");
case IPPROTO_TCP:
- return "TCP";
+ CASE("TCP");
case IPPROTO_UDP:
- return "UDP";
+ CASE("UDP");
case IPPROTO_ICMPV6:
- return "ICMPv6";
+ CASE("ICMPv6");
default:
- return "<unknown protocol>";
+ CASE("<unknown protocol>");
+#undef CASE
}
}
diff --git a/ip.h b/ip.h
index d0de6c8d..fb4119a7 100644
--- a/ip.h
+++ b/ip.h
@@ -118,6 +118,8 @@ static inline uint32_t ip6_get_flow_lbl(const struct ipv6hdr *ip6h)
}
bool ipv6_l4hdr(struct iov_tail *data, uint8_t *proto, size_t *dlen);
+
+#define IPPROTO_STRLEN (sizeof("<unknown protocol>"))
const char *ipproto_name(uint8_t proto);
/* IPv6 link-local all-nodes multicast address, ff02::1 */
--
2.53.0