1 /*
2   Copyright 2021 Northern.tech AS
3 
4   This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8   Free Software Foundation; version 3.
9 
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
18 
19   To the extent this program is licensed as part of the Enterprise
20   versions of CFEngine, the applicable Commercial Open Source License
21   (COSL) may apply to this file if you as a licensee so wish it. See
22   included file COSL.txt.
23 */
24 
25 #include <stdio.h>
26 #include <arpa/inet.h>
27 
28 #include <sequence.h>
29 #include <file_lib.h>
30 #include <logging.h>
31 #include <alloc.h>
32 
33 #include <proc_net_parsing.h>
34 
main()35 int main()
36 {
37     FILE *fp = fopen("/proc/net/tcp", "r");
38 
39     size_t buff_size = 256;
40     char *buff = xmalloc(buff_size);
41 
42     /* Read the header */
43     ssize_t ret = CfReadLine(&buff, &buff_size, fp);
44     if (ret == -1)
45     {
46         Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp");
47         free(buff);
48         return 1;
49     }
50 
51     /* Read real data */
52     Seq *lines = SeqNew(64, free);
53     ret = CfReadLines(&buff, &buff_size, fp, lines);
54     if (ret < 0)
55     {
56         Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp");
57         SeqDestroy(lines);
58         free(buff);
59         return 1;
60     }
61 
62     /* else */
63     char local_addr[INET_ADDRSTRLEN];
64     char remote_addr[INET_ADDRSTRLEN];
65     uint32_t l_port, r_port;
66     SocketState state;
67     for (size_t i = 0; i < (size_t) ret; i++)
68     {
69         char *line = SeqAt(lines,i);
70         if (ParseIPv4SocketInfo(line, local_addr, &l_port, remote_addr, &r_port, &state))
71         {
72             printf("%s:%d -> %s:%d%s\n",
73                    local_addr, l_port,
74                    remote_addr, r_port,
75                    (state == SOCK_STATE_LISTEN) ? " [LISTEN]" : "");
76         }
77     }
78     SeqClear(lines);
79 
80     char local_addr6[INET6_ADDRSTRLEN];
81     char remote_addr6[INET6_ADDRSTRLEN];
82     fp = fopen("/proc/net/tcp6", "r");
83     if (fp != NULL)
84     {
85         ret = CfReadLine(&buff, &buff_size, fp);
86         if (ret == -1)
87         {
88             Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp6");
89             SeqDestroy(lines);
90             free(buff);
91             return 1;
92         }
93 
94         /* Read real data */
95         ret = CfReadLines(&buff, &buff_size, fp, lines);
96         if (ret < 0)
97         {
98             Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp6");
99             SeqDestroy(lines);
100             free(buff);
101             return 1;
102         }
103 
104         /* else */
105         for (size_t i = 0; i < (size_t) ret; i++)
106         {
107             char *line = SeqAt(lines,i);
108             if (ParseIPv6SocketInfo(line, local_addr6, &l_port, remote_addr6, &r_port, &state))
109             {
110                 printf("%s:%d -> %s:%d%s\n",
111                        local_addr6, l_port,
112                        remote_addr6, r_port,
113                        (state == SOCK_STATE_LISTEN) ? " [LISTEN]" : "");
114             }
115         }
116         SeqClear(lines);
117     }
118 
119     fp = fopen("/proc/net/udp", "r");
120     ret = CfReadLine(&buff, &buff_size, fp);
121     if (ret == -1)
122     {
123         Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp");
124         SeqDestroy(lines);
125         free(buff);
126         return 1;
127     }
128 
129     /* Read real data */
130     ret = CfReadLines(&buff, &buff_size, fp, lines);
131     if (ret < 0)
132     {
133         Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp");
134         SeqDestroy(lines);
135         free(buff);
136         return 1;
137     }
138 
139     /* else */
140     for (size_t i = 0; i < (size_t) ret; i++)
141     {
142         char *line = SeqAt(lines,i);
143         if (ParseIPv4SocketInfo(line, local_addr, &l_port, remote_addr, &r_port, &state))
144         {
145             printf("%s:%d -> %s:%d [udp]\n",
146                    local_addr, l_port,
147                    remote_addr, r_port);
148         }
149     }
150     SeqClear(lines);
151 
152     fp = fopen("/proc/net/udp6", "r");
153     if (fp != NULL)
154     {
155         ret = CfReadLine(&buff, &buff_size, fp);
156         if (ret == -1)
157         {
158             Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp6");
159             SeqDestroy(lines);
160             free(buff);
161             return 1;
162         }
163 
164         /* Read real data */
165         ret = CfReadLines(&buff, &buff_size, fp, lines);
166         if (ret < 0)
167         {
168             Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp6");
169             SeqDestroy(lines);
170             free(buff);
171             return 1;
172         }
173 
174         /* else */
175         for (size_t i = 0; i < (size_t) ret; i++)
176         {
177             char *line = SeqAt(lines,i);
178             if (ParseIPv6SocketInfo(line, local_addr6, &l_port, remote_addr6, &r_port, &state))
179             {
180                 printf("%s:%d -> %s:%d [udp6]\n",
181                        local_addr6, l_port,
182                        remote_addr6, r_port);
183             }
184         }
185     }
186     SeqDestroy(lines);
187     free(buff);
188     return 0;
189 }
190