basic: convert ifname_valid_full() to take flags and allow numeric interfaces

This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2020-09-10 00:46:44 +02:00
parent 25b2d602b9
commit 2313524aa0
5 changed files with 38 additions and 21 deletions
+17 -10
View File
@@ -686,17 +686,19 @@ static const char* const ip_tos_table[] = {
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
bool ifname_valid_full(const char *p, bool alternative) {
bool ifname_valid_full(const char *p, IfnameValidFlags flags) {
bool numeric = true;
/* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
* but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We
* also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */
assert(!(flags & ~_IFNAME_VALID_ALL));
if (isempty(p))
return false;
if (alternative) {
if (flags & IFNAME_VALID_ALTERNATIVE) {
if (strlen(p) >= ALTIFNAMSIZ)
return false;
} else {
@@ -707,22 +709,27 @@ bool ifname_valid_full(const char *p, bool alternative) {
if (dot_or_dot_dot(p))
return false;
while (*p) {
if ((unsigned char) *p >= 127U)
for (const char *t = p; *t; t++) {
if ((unsigned char) *t >= 127U)
return false;
if ((unsigned char) *p <= 32U)
if ((unsigned char) *t <= 32U)
return false;
if (IN_SET(*p, ':', '/'))
if (IN_SET(*t, ':', '/'))
return false;
numeric = numeric && (*p >= '0' && *p <= '9');
p++;
numeric = numeric && (*t >= '0' && *t <= '9');
}
if (numeric)
return false;
if (numeric) {
if (!(flags & IFNAME_VALID_NUMERIC))
return false;
/* Verify that the number is well-formatted and in range. */
if (parse_ifindex(p) < 0)
return false;
}
return true;
}
+7 -2
View File
@@ -130,9 +130,14 @@ static inline int fd_inc_rcvbuf(int fd, size_t n) {
int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
bool ifname_valid_full(const char *p, bool alternative);
typedef enum {
IFNAME_VALID_ALTERNATIVE = 1 << 0,
IFNAME_VALID_NUMERIC = 1 << 1,
_IFNAME_VALID_ALL = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC,
} IfnameValidFlags;
bool ifname_valid_full(const char *p, IfnameValidFlags flags);
static inline bool ifname_valid(const char *p) {
return ifname_valid_full(p, false);
return ifname_valid_full(p, 0);
}
bool address_label_valid(const char *p);