1 /*
2 * Copyright (c) 2001 Stas Degteff <g@grumbler.org>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that: (1) source code distributions
6 * retain the above copyright notice and this paragraph in its entirety, (2)
7 * distributions including binary code include the above copyright notice and
8 * this paragraph in its entirety in the documentation or other materials
9 * provided with the distribution.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14 *
15 *
16 * BPFT - bpfilter trafic collector
17 *
18 * $Id: output.c,v 1.2 2002/10/18 03:28:27 stas_degteff Exp $
19 * Common functions for trafstat & traflog utilities.
20 *
21 */
22
23 #include <unistd.h>
24 #include <netinet/in.h>
25 #include <sys/param.h>
26 #include "output.h"
27 #include "traffic.h"
28
29 int
sortbyfrom(left,right)30 sortbyfrom(left, right)
31 register struct t_entry *left;
32 register struct t_entry *right;
33 {
34 if (htonl(left->in_ip.s_addr) < htonl(right->in_ip.s_addr))
35 return LESS;
36 if (htonl(left->in_ip.s_addr) > htonl(right->in_ip.s_addr))
37 return GREATER;
38 return EQUAL;
39 }
40
41 int
sortbyto(left,right)42 sortbyto(left, right)
43 register struct t_entry *left;
44 register struct t_entry *right;
45 {
46 if (htonl(left->out_ip.s_addr) < htonl(right->out_ip.s_addr))
47 return LESS;
48 if (htonl(left->out_ip.s_addr) > htonl(right->out_ip.s_addr))
49 return GREATER;
50 return EQUAL;
51 }
52
53 int
sortbypport(left,right)54 sortbypport(left, right)
55 register struct t_entry *left;
56 register struct t_entry *right;
57 {
58 if (htons(left->p_port) < htons(right->p_port))
59 return LESS;
60 if (htons(left->p_port) > htons(right->p_port))
61 return GREATER;
62 return EQUAL;
63 }
64
65 #if LAYOUT!=OLD
66 int
sortbyoport(left,right)67 sortbyoport(left, right)
68 register struct t_entry *left;
69 register struct t_entry *right;
70 {
71 if (htons(left->o_port) < htons(right->o_port))
72 return LESS;
73 if (htons(left->o_port) > htons(right->o_port))
74 return GREATER;
75 return EQUAL;
76 }
77 #endif
78
79 int
sortbysize(left,right)80 sortbysize(left, right)
81 register struct t_entry *left;
82 register struct t_entry *right;
83 {
84 if (left->n_psize < right->n_psize)
85 return GREATER;
86 if (left->n_psize > right->n_psize)
87 return LESS;
88 return EQUAL;
89 }
90
91
traf_print()92 traf_print()
93 {
94 register int i, j;
95 u_int64_t abytes = 0, dbytes = 0;
96 char buf[MAXHOSTNAMELEN + 1];
97 #if LAYOUT==OLD
98 char *port, *user, *proto;
99 #else
100 char *s_port, *d_port, *proto;
101 #endif
102 for (i = 0; i < s.t_size; i++)
103 abytes += sum[i].n_psize, dbytes += sum[i].n_bytes;
104 if (rflag) {
105 printf("%qu\n", abytes);
106 return;
107 }
108 qsort(sum, s.t_size, sizeof(struct t_entry), sortbysize);
109 switch ( order ){
110 case ORDER_TO:
111 qsort(sum, s.t_size, sizeof(struct t_entry), sortbyto);
112 break;
113 case ORDER_FROM:
114 qsort(sum, s.t_size, sizeof(struct t_entry), sortbyfrom);
115 break;
116 case ORDER_SIZE:
117 qsort(sum, s.t_size, sizeof(struct t_entry), sortbysize);
118 break;
119 case ORDER_DPORT:
120 qsort(sum, s.t_size, sizeof(struct t_entry), sortbypport);
121 break;
122 #if LAYOUT!=OLD
123 case ORDER_SPORT:
124 qsort(sum, s.t_size, sizeof(struct t_entry), sortbyoport);
125 break;
126 #endif
127 }
128 if (!fvnum) {
129 gethostname(buf, MAXHOSTNAMELEN);
130 printf("\n (%s) %s at", device_name, buf);
131 printf(" %.15s -", ctime((time_t *)&s.start) + 4);
132 printf(" %.15s\n", ctime((time_t *)&s.stop) + 4);
133 printf(" Summary: %qu data bytes, %qu all bytes, %u records\n",
134 dbytes, abytes, s.t_size);
135 printf("\
136 From Port To Port Proto Data All\n");
137 }
138 for (i = 0; i < s.t_size; i++) {
139 #if LAYOUT==OLD
140 port = "undef";
141 #else
142 s_port = "";
143 d_port = "";
144 #endif
145 switch(sum[i].ip_protocol) {
146 case IPPROTO_TCP:
147 if (sum[i].p_port || sum[i].o_port)
148 #if LAYOUT==OLD
149 port = tcpport_string(sum[i].p_port);
150 #else
151 s_port = tcpport_string(sum[i].o_port);
152 d_port = tcpport_string(sum[i].p_port);
153 #endif
154 proto = "tcp";
155 break;
156 case IPPROTO_UDP:
157 if (sum[i].p_port || sum[i].o_port)
158 #if LAYOUT==OLD
159 port = udpport_string(sum[i].p_port);
160 #else
161 s_port = udpport_string(sum[i].o_port);
162 d_port = udpport_string(sum[i].p_port);
163 #endif
164 proto = "udp";
165 break;
166 case IPPROTO_ICMP:
167 proto = "icmp";
168 break;
169 case IPPROTO_EGP:
170 proto = "egp";
171 break;
172 case IPPROTO_OSPF:
173 proto = "ospf";
174 break;
175 case IPPROTO_IGMP:
176 proto = "igmp";
177 break;
178 default:
179 proto = "unkn";
180 }
181 #if LAYOUT==OLD
182 if (sum[i].p_port) user = "client";
183 else user = "none";
184 #endif
185 if (!fvnum) {
186 #if LAYOUT==OLD
187 printf("%-18.18s %-6.6s ", ipaddr_string(&sum[i].in_ip),
188 (sum[i].who_srv & 1) ? port : user);
189 printf("%-18.18s %-6.6s ", ipaddr_string(&sum[i].out_ip),
190 (sum[i].who_srv & 2) ? port : user);
191 printf("%-4.4s %9ld %10ld\n", proto, sum[i].n_bytes,
192 sum[i].n_psize);
193 #else
194 printf("%-18.18s %-6.6s ", ipaddr_string(&sum[i].in_ip),
195 s_port);
196 printf("%-18.18s %-6.6s ", ipaddr_string(&sum[i].out_ip),
197 d_port);
198 printf("%-4.4s %9ld %10ld\n", proto, sum[i].n_bytes,
199 sum[i].n_psize);
200 #endif
201 } else
202 for (j = 0; j < fvnum; j++)
203 switch (fv[j].cmd) {
204 case FROM:
205 printf(fv[j].format, ipaddr_string(&sum[i].in_ip));
206 break;
207 case TO:
208 printf(fv[j].format, ipaddr_string(&sum[i].out_ip));
209 break;
210 #if LAYOUT==OLD
211 case SPORT:
212 printf(fv[j].format,
213 (sum[i].who_srv & 1) ? port : user);
214 break;
215 case DPORT:
216 printf(fv[j].format,
217 (sum[i].who_srv & 2) ? port : user);
218 break;
219 #else
220 case SPORT:
221 printf(fv[j].format,
222 s_port);
223 break;
224 case DPORT:
225 printf(fv[j].format,
226 d_port);
227 break;
228 #endif
229 case PROTO:
230 printf(fv[j].format, proto);
231 break;
232 case BYTES:
233 printf(fv[j].format, sum[i].n_bytes);
234 break;
235 case PSIZE:
236 printf(fv[j].format, sum[i].n_psize);
237 break;
238 case FTIME:
239 strftime(buf, sizeof(buf), fv[j].format,
240 localtime((time_t *)&s.start));
241 printf("%s", buf);
242 break;
243 case LTIME:
244 strftime(buf, sizeof(buf), fv[j].format,
245 localtime((time_t *)&s.stop));
246 printf("%s", buf);
247 break;
248 }
249 }
250 }
251
252
253 /*
254 * Put traffic table to fd in binary form.
255 */
256 void
traf_put(fd)257 traf_put(fd)
258 register int fd;
259 {
260 register int i;
261 int c = 0;
262
263 c += write(fd, (int *)&n_entry, sizeof(n_entry));
264 c += write(fd, (struct timeval *)&start_time, sizeof(start_time));
265 c += write(fd, (struct timeval *)&drop_time, sizeof(drop_time));
266 for (i = 0; i < n_entry; i++) {
267 c += write(fd, (struct t_entry *)&entries[i],
268 sizeof(struct t_entry));
269 }
270 (void)write(fd, (int *)&c, sizeof(c));
271 return;
272 }
273
traf_write(fd)274 traf_write(fd)
275 FILE *fd;
276 {
277 if (fwrite((struct t_header *)&s, sizeof(struct t_header), 1, fd) != 1)
278 error("write header error");
279 if (fwrite((struct t_entry *)sum, sizeof(struct t_entry), s.t_size, fd) != s.t_size)
280 error("write table error");
281 return;
282 }
283