diff options
Diffstat (limited to 'src/firemon/route.c')
-rw-r--r-- | src/firemon/route.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/src/firemon/route.c b/src/firemon/route.c new file mode 100644 index 000000000..7f559c7b5 --- /dev/null +++ b/src/firemon/route.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014, 2015 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firemon.h" | ||
21 | #include <assert.h> | ||
22 | #include <arpa/inet.h> | ||
23 | #define MAXBUF 4096 | ||
24 | |||
25 | typedef struct iflist_t { | ||
26 | struct iflist_t *next; | ||
27 | uint32_t ip; | ||
28 | } IfList; | ||
29 | static IfList *ifs = NULL; | ||
30 | static char last_start[MAXBUF + 1]; | ||
31 | |||
32 | static IfList *list_find(uint32_t ip, uint32_t mask) { | ||
33 | IfList *ptr = ifs; | ||
34 | while (ptr) { | ||
35 | if ((ptr->ip & mask) == (ip & mask)) | ||
36 | return ptr; | ||
37 | ptr = ptr->next; | ||
38 | } | ||
39 | |||
40 | return NULL; | ||
41 | } | ||
42 | |||
43 | static void extract_if(const char *fname) { | ||
44 | // clear interface list | ||
45 | while (ifs) { | ||
46 | IfList *tmp = ifs->next; | ||
47 | free(ifs); | ||
48 | ifs = tmp; | ||
49 | } | ||
50 | assert(ifs == NULL); | ||
51 | |||
52 | FILE *fp = fopen(fname, "r"); | ||
53 | if (!fp) | ||
54 | return; | ||
55 | |||
56 | char buf[MAXBUF]; | ||
57 | int state = 0; // 0 -wait for Local | ||
58 | // | ||
59 | while (fgets(buf, MAXBUF, fp)) { | ||
60 | // remove blanks, \n | ||
61 | char *ptr = buf; | ||
62 | while (*ptr == ' ' || *ptr == '\t') | ||
63 | ptr++; | ||
64 | char *start = ptr; | ||
65 | if (*start == '\0') | ||
66 | continue; | ||
67 | ptr = strchr(ptr, '\n'); | ||
68 | if (ptr) | ||
69 | *ptr = '\0'; | ||
70 | |||
71 | if (state == 0) { | ||
72 | if (strncmp(buf, "Local:", 6) == 0) { | ||
73 | state = 1; | ||
74 | continue; | ||
75 | } | ||
76 | } | ||
77 | else if (state == 1) { | ||
78 | // remove broadcast addresses | ||
79 | if (strstr(start,"BROADCAST")) | ||
80 | continue; | ||
81 | else if (*start == '+') | ||
82 | continue; | ||
83 | else if (*start == '|') { | ||
84 | memset(last_start, 0, MAXBUF + 1); | ||
85 | strncpy(last_start, start, MAXBUF); | ||
86 | continue; | ||
87 | } | ||
88 | else if (strstr(buf, "LOCAL")) { | ||
89 | // printf("%s %s\n", last_start, start); | ||
90 | unsigned mbits; | ||
91 | sscanf(start, "/%u", &mbits); | ||
92 | if (mbits != 32) | ||
93 | continue; | ||
94 | |||
95 | unsigned a, b, c, d; | ||
96 | if (sscanf(last_start, "|-- %u.%u.%u.%u", &a, &b, &c, &d) != 4 || a > 255 || b > 255 || c > 255 || d > 255) | ||
97 | continue; | ||
98 | |||
99 | IfList *newif = malloc(sizeof(IfList)); | ||
100 | if (!newif) | ||
101 | errExit("malloc"); | ||
102 | newif->ip = a * 0x1000000 + b * 0x10000 + c * 0x100 + d; | ||
103 | newif->next = ifs; | ||
104 | ifs = newif; | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
109 | fclose(fp); | ||
110 | |||
111 | |||
112 | } | ||
113 | |||
114 | static void print_route(const char *fname) { | ||
115 | FILE *fp = fopen(fname, "r"); | ||
116 | if (!fp) | ||
117 | return; | ||
118 | |||
119 | printf(" Route table:\n"); | ||
120 | char buf[MAXBUF]; | ||
121 | while (fgets(buf, MAXBUF, fp)) { | ||
122 | // remove blanks, \n | ||
123 | char *ptr = buf; | ||
124 | while (*ptr == ' ' || *ptr == '\t') | ||
125 | ptr++; | ||
126 | char *start = ptr; | ||
127 | if (*start == '\0') | ||
128 | continue; | ||
129 | ptr = strchr(ptr, '\n'); | ||
130 | if (ptr) | ||
131 | *ptr = '\0'; | ||
132 | |||
133 | // remove table header | ||
134 | //Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT | ||
135 | if (strncmp(start, "Iface", 5) == 0) | ||
136 | continue; | ||
137 | |||
138 | // extract data | ||
139 | char ifname[64]; | ||
140 | char destination[64]; | ||
141 | char gateway[64]; | ||
142 | char flags[64]; | ||
143 | char refcnt[64]; | ||
144 | char use[64]; | ||
145 | char metric[64]; | ||
146 | char mask[64]; | ||
147 | int rv = sscanf(start, "%s %s %s %s %s %s %s %s\n", ifname, destination, gateway, flags, refcnt, use, metric, mask); | ||
148 | if (rv != 8) | ||
149 | continue; | ||
150 | |||
151 | // destination ip | ||
152 | uint32_t destip; | ||
153 | sscanf(destination, "%x", &destip); | ||
154 | destip = ntohl(destip); | ||
155 | uint32_t destmask; | ||
156 | sscanf(mask, "%x", &destmask); | ||
157 | destmask = ntohl(destmask); | ||
158 | uint32_t gw; | ||
159 | sscanf(gateway, "%x", &gw); | ||
160 | gw = ntohl(gw); | ||
161 | |||
162 | // printf("#%s# #%s# #%s# #%s# #%s# #%s# #%s# #%s#\n", ifname, destination, gateway, flags, refcnt, use, metric, mask); | ||
163 | if (gw != 0) | ||
164 | printf(" %u.%u.%u.%u/%u via %u.%u.%u.%u, dev %s, metric %s\n", | ||
165 | PRINT_IP(destip), mask2bits(destmask), | ||
166 | PRINT_IP(gw), | ||
167 | ifname, | ||
168 | metric); | ||
169 | else { // this is an interface | ||
170 | IfList *ifentry = list_find(destip, destmask); | ||
171 | if (ifentry) { | ||
172 | printf(" %u.%u.%u.%u/%u, dev %s, scope link src %d.%d.%d.%d\n", | ||
173 | PRINT_IP(destip), mask2bits(destmask), | ||
174 | ifname, | ||
175 | PRINT_IP(ifentry->ip)); | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | |||
180 | fclose(fp); | ||
181 | |||
182 | } | ||
183 | |||
184 | void route(pid_t pid) { | ||
185 | if (getuid() == 0) | ||
186 | firemon_drop_privs(); | ||
187 | |||
188 | pid_read(pid); | ||
189 | |||
190 | // print processes | ||
191 | int i; | ||
192 | for (i = 0; i < max_pids; i++) { | ||
193 | if (pids[i].level == 1) { | ||
194 | pid_print_list(i, 0); | ||
195 | int child = find_child(i); | ||
196 | if (child != -1) { | ||
197 | char *fname; | ||
198 | if (asprintf(&fname, "/proc/%d/net/fib_trie", child) == -1) | ||
199 | errExit("asprintf"); | ||
200 | extract_if(fname); | ||
201 | free(fname); | ||
202 | |||
203 | if (asprintf(&fname, "/proc/%d/net/route", child) == -1) | ||
204 | errExit("asprintf"); | ||
205 | print_route(fname); | ||
206 | free(fname); | ||
207 | printf("\n"); | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | |||