1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <errno.h>
4 #include <netinet/in.h>
5 
6 #include "alloc-util.h"
7 #include "ip-protocol-list.h"
8 #include "macro.h"
9 #include "parse-util.h"
10 #include "string-util.h"
11 
12 static const struct ip_protocol_name* lookup_ip_protocol(register const char *str, register GPERF_LEN_TYPE len);
13 
14 #include "ip-protocol-from-name.h"
15 #include "ip-protocol-to-name.h"
16 
ip_protocol_to_name(int id)17 const char *ip_protocol_to_name(int id) {
18 
19         if (id < 0)
20                 return NULL;
21 
22         if ((size_t) id >= ELEMENTSOF(ip_protocol_names))
23                 return NULL;
24 
25         return ip_protocol_names[id];
26 }
27 
ip_protocol_from_name(const char * name)28 int ip_protocol_from_name(const char *name) {
29         const struct ip_protocol_name *sc;
30 
31         assert(name);
32 
33         sc = lookup_ip_protocol(name, strlen(name));
34         if (!sc)
35                 return -EINVAL;
36 
37         return sc->id;
38 }
39 
parse_ip_protocol(const char * s)40 int parse_ip_protocol(const char *s) {
41         _cleanup_free_ char *str = NULL;
42         int i, r;
43 
44         assert(s);
45 
46         if (isempty(s))
47                 return IPPROTO_IP;
48 
49         /* Do not use strdupa() here, as the input string may come from *
50          * command line or config files. */
51         str = strdup(s);
52         if (!str)
53                 return -ENOMEM;
54 
55         i = ip_protocol_from_name(ascii_strlower(str));
56         if (i >= 0)
57                 return i;
58 
59         r = safe_atoi(str, &i);
60         if (r < 0)
61                 return r;
62 
63         if (!ip_protocol_to_name(i))
64                 return -EINVAL;
65 
66         return i;
67 }
68 
ip_protocol_to_tcp_udp(int id)69 const char *ip_protocol_to_tcp_udp(int id) {
70         return IN_SET(id, IPPROTO_TCP, IPPROTO_UDP) ?
71                 ip_protocol_to_name(id) : NULL;
72 }
73 
ip_protocol_from_tcp_udp(const char * ip_protocol)74 int ip_protocol_from_tcp_udp(const char *ip_protocol) {
75         int id = ip_protocol_from_name(ip_protocol);
76         return IN_SET(id, IPPROTO_TCP, IPPROTO_UDP) ? id : -EINVAL;
77 }
78