1 /*
2 * Argus Software
3 * Copyright (c) 2000-2016 QoSient, LLC
4 * All rights reserved.
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, or (at your option)
9 * 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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22 /*
23 * $Id: //depot/argus/clients/examples/radump/radump.c#11 $
24 * $DateTime: 2016/06/01 15:17:28 $
25 * $Change: 3148 $
26 */
27
28 /*
29 * radump.c - dump payload as if its tcpdump data.
30 */
31
32
33 #ifdef HAVE_CONFIG_H
34 #include "argus_config.h"
35 #endif
36
37 #include <unistd.h>
38 #include <stdlib.h>
39
40 #include <argus_compat.h>
41
42 #include <rabins.h>
43 #include <argus_util.h>
44 #include <argus_client.h>
45 #include <argus_main.h>
46 #include <argus_filter.h>
47
48 #ifndef IPPROTO_PIM
49 #define IPPROTO_PIM 103
50 #endif
51
52
53 #define RaDump 1
54 #include <oui.h>
55
56 #include <signal.h>
57 #include <ctype.h>
58
59 #include "interface.h"
60
61 const u_char *snapend = NULL;
62
63 char ArgusBuf[MAXSTRLEN];
64
65 /* draft-ietf-pwe3-iana-allocation-04 */
66 struct tok l2vpn_encaps_values[] = {
67 { 0x00, "Reserved"},
68 { 0x01, "Frame Relay"},
69 { 0x02, "ATM AAL5 VCC transport"},
70 { 0x03, "ATM transparent cell transport"},
71 { 0x04, "Ethernet VLAN"},
72 { 0x05, "Ethernet"},
73 { 0x06, "Cisco-HDLC"},
74 { 0x07, "PPP"},
75 { 0x08, "SONET/SDH Circuit Emulation Service over MPLS"},
76 { 0x09, "ATM n-to-one VCC cell transport"},
77 { 0x0a, "ATM n-to-one VPC cell transport"},
78 { 0x0b, "IP Layer2 Transport"},
79 { 0x0c, "ATM one-to-one VCC Cell Mode"},
80 { 0x0d, "ATM one-to-one VPC Cell Mode"},
81 { 0x0e, "ATM AAL5 PDU VCC transport"},
82 { 0x0f, "Frame-Relay Port mode"},
83 { 0x10, "SONET/SDH Circuit Emulation over Packet"},
84 { 0x11, "Structure-agnostic E1 over Packet"},
85 { 0x12, "Structure-agnostic T1 (DS1) over Packet"},
86 { 0x13, "Structure-agnostic E3 over Packet"},
87 { 0x14, "Structure-agnostic T3 (DS3) over Packet"},
88 { 0x15, "CESoPSN basic mode"},
89 { 0x16, "TDMoIP basic mode"},
90 { 0x17, "CESoPSN TDM with CAS"},
91 { 0x18, "TDMoIP TDM with CAS"},
92 { 0x40, "IP-interworking"},
93 { 0, NULL}
94 };
95
96
97 int ArgusThisEflag = 0;
98
99 void
ArgusClientInit(struct ArgusParserStruct * parser)100 ArgusClientInit (struct ArgusParserStruct *parser)
101 {
102 parser->RaWriteOut = 1;
103
104 if (!(parser->RaInitialized)) {
105
106 /*
107 the library sets signal handling routines for
108 SIGHUP, SIGTERM, SIGQUIT, SIGINT, SIGUSR1, and SIGUSR2.
109 SIGHUP doesn't do anything, SIGTERM, SIGQUIT, and SIGINT
110 call the user supplied RaParseComplete(). SIGUSR1 and
111 SIGUSR2 modify the debug level so if compiled with
112 ARGUS_DEBUG support, programs can start generating
113 debug information. USR1 increments by 1, USR2 sets
114 it back to zero.
115
116 */
117 (void) signal (SIGHUP, (void (*)(int)) RaParseComplete);
118 ArgusThisEflag = parser->eflag;
119 parser->eflag = ARGUS_HEXDUMP;
120 parser->RaInitialized++;
121 }
122 }
123
RaArgusInputComplete(struct ArgusInput * input)124 void RaArgusInputComplete (struct ArgusInput *input) {};
125
126 void
RaParseComplete(int sig)127 RaParseComplete (int sig)
128 {
129 if (sig >= 0) {
130 ArgusShutDown(sig);
131 if ((sig == SIGINT) || (sig == SIGQUIT))
132 exit(0);
133 }
134 }
135
136
137 void
ArgusClientTimeout()138 ArgusClientTimeout ()
139 {
140 #ifdef ARGUSDEBUG
141 ArgusDebug (6, "ArgusClientTimeout()\n");
142 #endif
143 }
144
145 void
parse_arg(int argc,char ** argv)146 parse_arg (int argc, char**argv)
147 {}
148
149 void
usage()150 usage ()
151 {
152 extern char version[];
153
154 fprintf (stdout, "Ratemplate Version %s\n", version);
155 fprintf (stdout, "usage: %s \n", ArgusParser->ArgusProgramName);
156 fprintf (stdout, "usage: %s [options] [ra-options] [- filter-expression]\n", ArgusParser->ArgusProgramName);
157
158 fprintf (stdout, "options: -v print verbose protocol information.\n");
159 fprintf (stdout, " -s +suser dump the source user data buffer.\n");
160 fprintf (stdout, " +duser dump the destination user buffer.\n");
161 fflush (stdout);
162 exit(1);
163 }
164
165 char * RaDumpUserBuffer (struct ArgusParserStruct *, struct ArgusRecordStruct *, int, int);
166
167 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)168 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
169 {
170 char buf[MAXSTRLEN];
171 int i, srcdata = 0, dstdata = 0;
172
173 if (parser->Lflag && !(parser->ArgusPrintXml)) {
174 if (parser->RaLabel == NULL) {
175 int eflag = parser->eflag;
176 parser->eflag = ArgusThisEflag;
177 parser->RaLabel = ArgusGenerateLabel(parser, argus);
178 parser->eflag = eflag;
179 }
180
181 if (!(parser->RaLabelCounter++ % parser->Lflag))
182 if (printf ("%s\n", parser->RaLabel) < 0)
183 RaParseComplete (SIGQUIT);
184
185 if (parser->Lflag < 0)
186 parser->Lflag = 0;
187 }
188
189 if (argus->hdr.type & ARGUS_MAR) {
190 } else {
191 bzero (buf, MAXSTRLEN);
192 ArgusPrintRecord(ArgusParser, buf, argus, MAXSTRLEN);
193
194 fprintf (stdout, "%s", buf);
195
196 bzero (ArgusBuf, MAXSTRLEN);
197 for (i = 0; i < MAX_PRINT_ALG_TYPES; i++) {
198 if (parser->RaPrintAlgorithmList[i] != NULL) {
199 if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintSrcUserData)
200 srcdata = parser->RaPrintAlgorithmList[i]->length;
201
202 if (parser->RaPrintAlgorithmList[i]->print == ArgusPrintDstUserData) {
203 dstdata = parser->RaPrintAlgorithmList[i]->length;
204 }
205 }
206 }
207
208 if (srcdata || dstdata) {
209 if ((parser->RaFieldDelimiter != ' ') && (parser->RaFieldDelimiter != '\0'))
210 fprintf (stdout, "%c", parser->RaFieldDelimiter);
211 else
212 fprintf (stdout, " ");
213 }
214
215 if (srcdata) {
216 struct ArgusDataStruct *user = (struct ArgusDataStruct *)argus->dsrs[ARGUS_SRCUSERDATA_INDEX];
217 int slen;
218 char *str;
219
220 if (user != NULL) {
221 slen = (user->hdr.argus_dsrvl16.len - 2 ) * 4;
222 slen = (user->count < slen) ? user->count : slen;
223 slen = (slen > srcdata) ? srcdata : slen;
224 }
225
226 if ((str = RaDumpUserBuffer (parser, argus, ARGUS_SRCUSERDATA_INDEX, 8196)) != NULL) {
227 int stlen = 0, blen = 0;
228 char lbuf[64];
229 sprintf (buf, "s[%d]=", srcdata);
230 blen = strlen(buf);
231 stlen = strlen(str);
232 sprintf (lbuf, "s[%d]=", (stlen > srcdata) ? srcdata : stlen);
233 sprintf (buf, "%*.*s", blen, blen, lbuf);
234 sprintf (&buf[strlen(buf)], "\"%s", str);
235 buf[srcdata - 1] = '\0';
236 #if defined(HAVE_STRLCAT)
237 strlcat(buf, "\"", MAXSTRLEN - strlen(buf));
238 #else
239 strcat(buf, "\"");
240 #endif
241 fprintf (stdout, "%-*.*s", srcdata, srcdata, buf);
242 bzero (ArgusBuf, MAXSTRLEN);
243
244 if ((parser->RaFieldDelimiter != ' ') && (parser->RaFieldDelimiter != '\0'))
245 fprintf (stdout, "%c", parser->RaFieldDelimiter);
246 else
247 fprintf (stdout, " ");
248 }
249 }
250
251
252 if (dstdata) {
253 struct ArgusDataStruct *user = (struct ArgusDataStruct *)argus->dsrs[ARGUS_DSTUSERDATA_INDEX];
254 int slen;
255 char *str;
256
257 if (user != NULL) {
258 slen = (user->hdr.argus_dsrvl16.len - 2 ) * 4;
259 slen = (user->count < slen) ? user->count : slen;
260 slen = (slen > dstdata) ? dstdata : slen;
261 }
262
263 if ((str = RaDumpUserBuffer (parser, argus, ARGUS_DSTUSERDATA_INDEX, 8196)) != NULL) {
264 int stlen = 0, blen = 0;
265 char lbuf[64];
266 sprintf (buf, "d[%d]=", dstdata);
267 blen = strlen(buf);
268 stlen = strlen(str);
269 sprintf (lbuf, "d[%d]=", (stlen > dstdata) ? dstdata : stlen);
270 sprintf (buf, "%*.*s", blen, blen, lbuf);
271 sprintf (&buf[strlen(buf)], "\"%s", str);
272 buf[dstdata - 1] = '\0';
273 #if defined(HAVE_STRLCAT)
274 strlcat(buf, "\"", MAXSTRLEN - strlen(buf));
275 #else
276 strcat(buf, "\"");
277 #endif
278 fprintf (stdout, "%-*.*s", dstdata, dstdata, buf);
279 bzero (ArgusBuf, MAXSTRLEN);
280 }
281 }
282
283 fprintf (stdout, "\n");
284 fflush(stdout);
285 }
286 }
287
288
289 char *
RaDumpUserBuffer(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus,int ind,int len)290 RaDumpUserBuffer (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus, int ind, int len)
291 {
292 struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
293 unsigned short sport = 0, dport = 0;
294 int type, proto, process = 0;
295 struct ArgusDataStruct *user = NULL;
296 u_char buf[MAXSTRLEN], *bp = NULL;
297 int slen = 0, done = 0;
298
299 if ((user = (struct ArgusDataStruct *)argus->dsrs[ind]) == NULL)
300 return (ArgusBuf);
301
302 /*
303 switch (ind) {
304 case ARGUS_SRCUSERDATA_INDEX:
305 dchr = 's';
306 break;
307 case ARGUS_DSTUSERDATA_INDEX:
308 dchr = 'd';
309 break;
310 }
311 */
312
313 bp = (u_char *) &user->array;
314 slen = (user->hdr.argus_dsrvl16.len - 2 ) * 4;
315 slen = (user->count < slen) ? user->count : slen;
316 slen = (slen > len) ? len : slen;
317 snapend = bp + slen;
318
319 if (flow != NULL) {
320 switch (flow->hdr.subtype & 0x3F) {
321 case ARGUS_FLOW_CLASSIC5TUPLE: {
322 switch ((type = flow->hdr.argus_dsrvl8.qual & 0x1F)) {
323 case ARGUS_TYPE_IPV4:
324 switch (flow->ip_flow.ip_p) {
325 case IPPROTO_TCP:
326 case IPPROTO_UDP: {
327 proto = flow->ip_flow.ip_p;
328 sport = flow->ip_flow.sport;
329 dport = flow->ip_flow.dport;
330 process++;
331 break;
332 }
333 case IPPROTO_IGMP: {
334 struct ArgusMetricStruct *metric = (void *)argus->dsrs[ARGUS_METRIC_INDEX];
335 if ((metric != NULL) && (((ind == ARGUS_SRCUSERDATA_INDEX) && metric->src.pkts) ||
336 ((ind == ARGUS_DSTUSERDATA_INDEX) && metric->dst.pkts))) {
337 igmp_print(bp, slen);
338 done++;
339 break;
340 }
341 }
342
343 case IPPROTO_PIM: {
344 struct ArgusMetricStruct *metric = (void *)argus->dsrs[ARGUS_METRIC_INDEX];
345 if ((metric != NULL) && (((ind == ARGUS_SRCUSERDATA_INDEX) && metric->src.pkts) ||
346 ((ind == ARGUS_DSTUSERDATA_INDEX) && metric->dst.pkts))) {
347 pim_print(bp, slen);
348 done++;
349 break;
350 }
351 }
352 }
353 break;
354 case ARGUS_TYPE_IPV6: {
355 switch (flow->ipv6_flow.ip_p) {
356 case IPPROTO_TCP:
357 case IPPROTO_UDP: {
358 proto = flow->ipv6_flow.ip_p;
359 sport = flow->ipv6_flow.sport;
360 dport = flow->ipv6_flow.dport;
361 process++;
362 break;
363 }
364
365 case IPPROTO_PIM: {
366 struct ArgusMetricStruct *metric = (void *)argus->dsrs[ARGUS_METRIC_INDEX];
367
368 if ((metric != NULL) && (((ind == ARGUS_SRCUSERDATA_INDEX) && metric->src.pkts) ||
369 ((ind == ARGUS_DSTUSERDATA_INDEX) && metric->dst.pkts))) {
370 pim_print(bp, slen);
371 done++;
372 break;
373 }
374 }
375 }
376 break;
377 }
378 case ARGUS_TYPE_ARP: {
379 if (ind == ARGUS_SRCUSERDATA_INDEX) {
380 arp_src_print(parser, argus);
381 }
382 if (ind == ARGUS_DSTUSERDATA_INDEX) {
383 arp_dst_print(parser, argus);
384 }
385 done++;
386 break;
387 }
388 /*
389 struct ArgusMacFlow {
390 struct ether_header ehdr;
391 unsigned char dsap, ssap;
392 };
393
394 */
395
396 case ARGUS_TYPE_ETHER: {
397 if (flow != NULL)
398 if ((flow->mac_flow.mac_union.ether.ssap == LLCSAP_BPDU) &&
399 (flow->mac_flow.mac_union.ether.dsap == LLCSAP_BPDU))
400 stp_print (bp, slen);
401 done++;
402 break;
403 }
404 }
405 break;
406 }
407
408 case ARGUS_FLOW_ARP: {
409 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
410 case ARGUS_TYPE_RARP:
411 case ARGUS_TYPE_ARP:
412 if (ind == ARGUS_SRCUSERDATA_INDEX) {
413 arp_src_print(parser, argus);
414 }
415 if (ind == ARGUS_DSTUSERDATA_INDEX) {
416 arp_dst_print(parser, argus);
417 }
418 done++;
419 break;
420 }
421 }
422 }
423 }
424
425 if (process && bp) {
426 *(int *)&buf = 0;
427
428 #define ISPORT(p) (dport == (p) || sport == (p))
429
430 switch (proto) {
431 case IPPROTO_TCP: {
432 if (ISPORT(BGP_PORT))
433 bgp_print(bp, slen);
434 else if (ISPORT(TELNET_PORT))
435 telnet_print(bp, slen);
436 else if (ISPORT(PPTP_PORT))
437 pptp_print(bp, slen);
438 else if (ISPORT(NETBIOS_SSN_PORT))
439 nbt_tcp_print(bp, slen);
440 else if (ISPORT(BEEP_PORT))
441 beep_print(bp, slen);
442 else if (ISPORT(NAMESERVER_PORT) || ISPORT(MULTICASTDNS_PORT))
443 ns_print(bp + 2, slen - 2, 0);
444 else if (ISPORT(MSDP_PORT))
445 msdp_print(bp, slen);
446 else if (ISPORT(LDP_PORT))
447 ldp_print(bp, slen);
448 else {
449 parser->eflag = ArgusThisEflag;
450 ArgusEncode (parser, (const char *)bp, NULL, slen, ArgusBuf, sizeof(ArgusBuf));
451 parser->eflag = ARGUS_HEXDUMP;
452 }
453 break;
454 }
455
456 case IPPROTO_UDP: {
457 if (ISPORT(NAMESERVER_PORT))
458 ns_print(bp, slen, 0);
459 else if (ISPORT(MULTICASTDNS_PORT))
460 ns_print(bp, slen, 1);
461 else if (ISPORT(NTP_PORT))
462 ntp_print(bp, slen);
463 else if (ISPORT(LDP_PORT))
464 ldp_print(bp, slen);
465 else if (ISPORT(RADIUS_PORT) || ISPORT(RADIUS_NEW_PORT) ||
466 ISPORT(RADIUS_ACCOUNTING_PORT) ||
467 ISPORT(RADIUS_NEW_ACCOUNTING_PORT) )
468 radius_print(bp, slen);
469 else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT))
470 krb_print(bp, slen);
471 else if (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT))
472 snmp_print(bp, slen);
473 else if (ISPORT(TIMED_PORT))
474 timed_print(bp, slen);
475 else if (ISPORT(TFTP_PORT))
476 tftp_print(bp, slen);
477 else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS))
478 bootp_print(bp, slen);
479 else if (ISPORT(RIP_PORT))
480 rip_print(bp, slen);
481 else if (ISPORT(AODV_PORT))
482 aodv_print(bp, slen, 0);
483 else if (ISPORT(L2TP_PORT))
484 l2tp_print(bp, slen);
485 else if (ISPORT(SYSLOG_PORT))
486 syslog_print(bp, slen);
487 else if (ISPORT(LMP_PORT))
488 lmp_print(bp, slen);
489 else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) ||
490 (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH))
491 rx_print(bp, slen, sport, dport);
492 else if (dport == BFD_CONTROL_PORT || dport == BFD_ECHO_PORT )
493 bfd_print(bp, slen, dport);
494 else if (ISPORT(NETBIOS_NS_PORT))
495 nbt_udp137_print(bp, slen);
496 else if (ISPORT(NETBIOS_DGRAM_PORT))
497 nbt_udp138_print(bp, slen);
498 else if (ISPORT(ISAKMP_PORT))
499 isakmp_print(bp, slen);
500 else if (ISPORT(ISAKMP_PORT_NATT))
501 isakmp_rfc3948_print(bp, slen);
502 else if (ISPORT(ISAKMP_PORT_USER1) || ISPORT(ISAKMP_PORT_USER2))
503 isakmp_print(bp, slen);
504 else {
505 parser->eflag = ArgusThisEflag;
506 ArgusEncode (parser, (const char *)bp, NULL, slen, ArgusBuf, sizeof(ArgusBuf));
507 parser->eflag = ARGUS_HEXDUMP;
508 }
509 /*
510 else if (ISPORT(3456))
511 vat_print(bp, slen);
512 else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT))
513 zephyr_print(bp, slen);
514 else if (ISPORT(RIPNG_PORT))
515 ripng_print(bp, slen);
516 else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT))
517 dhcp6_print(bp, slen);
518 else if (dport == 4567)
519 wb_print(bp, slen);
520 else if (ISPORT(CISCO_AUTORP_PORT))
521 cisco_autorp_print(bp, slen);
522 else if (ISPORT(RADIUS_PORT) || ISPORT(RADIUS_NEW_PORT) ||
523 ISPORT(RADIUS_ACCOUNTING_PORT) || ISPORT(RADIUS_NEW_ACCOUNTING_PORT) )
524 radius_print(bp, slen);
525 else if (dport == HSRP_PORT)
526 hsrp_print(bp, slen);
527 else if (ISPORT(LWRES_PORT))
528 lwres_print(bp, slen);
529 else if (ISPORT(MPLS_LSP_PING_PORT))
530 lspping_print(bp, slen);
531 */
532 }
533 }
534 }
535
536 return (ArgusBuf);
537 }
538
RaSendArgusRecord(struct ArgusRecordStruct * argus)539 int RaSendArgusRecord(struct ArgusRecordStruct *argus) {return 0;}
540
541 void ArgusWindowClose(void);
542
ArgusWindowClose(void)543 void ArgusWindowClose(void) {
544 #ifdef ARGUSDEBUG
545 ArgusDebug (6, "ArgusWindowClose () returning\n");
546 #endif
547 }
548
549 /*
550 * Print out a null-terminated filename (or other ascii string).
551 * If ep is NULL, assume no truncation check is needed.
552 * Return true if truncated.
553 */
554 int
fn_print(register const u_char * s,register const u_char * ep,char * buf)555 fn_print(register const u_char *s, register const u_char *ep, char *buf)
556 {
557 register int ret;
558 register u_char c;
559
560 ret = 1; /* assume truncated */
561 while (ep == NULL || s < ep) {
562 c = *s++;
563 if (c == '\0') {
564 ret = 0;
565 break;
566 }
567 if (!isascii(c)) {
568 c = toascii(c);
569 sprintf(&buf[strlen(buf)], "%c", 'M');
570 sprintf(&buf[strlen(buf)], "%c", '-');
571 }
572 if (!isprint(c)) {
573 c ^= 0x40; /* DEL to ?, others to alpha */
574 sprintf(&buf[strlen(buf)], "%c", '^');
575 }
576 sprintf(&buf[strlen(buf)], "%c", c);
577 }
578 return(ret);
579 }
580
581 /*
582 * Print out a counted filename (or other ascii string).
583 * If ep is NULL, assume no truncation check is needed.
584 * Return true if truncated.
585 */
586 int
fn_printn(register const u_char * s,register u_int n,register const u_char * ep,char * buf)587 fn_printn(register const u_char *s, register u_int n,
588 register const u_char *ep, char *buf)
589 {
590 register u_char c;
591
592 while (n > 0 && (ep == NULL || s < ep)) {
593 n--;
594 c = *s++;
595 if (!isascii(c)) {
596 c = toascii(c);
597 sprintf(&buf[strlen(buf)], "%c", 'M');
598 sprintf(&buf[strlen(buf)], "%c", '-');
599 }
600 if (!isprint(c)) {
601 c ^= 0x40; /* DEL to ?, others to alpha */
602 sprintf(&buf[strlen(buf)], "%c", '^');
603 }
604 sprintf(&buf[strlen(buf)], "%c", c);
605 }
606 return (n == 0) ? 0 : 1;
607 }
608
609 /*
610 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
611 * The Regents of the University of California. All rights reserved.
612 *
613 * Redistribution and use in source and binary forms, with or without
614 * modification, are permitted provided that: (1) source code distributions
615 * retain the above copyright notice and this paragraph in its entirety, (2)
616 * distributions including binary code include the above copyright notice and
617 * this paragraph in its entirety in the documentation or other materials
618 * provided with the distribution, and (3) all advertising materials mentioning
619 * features or use of this software display the following acknowledgement:
620 * ``This product includes software developed by the University of California,
621 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
622 * the University nor the names of its contributors may be used to endorse
623 * or promote products derived from this software without specific prior
624 * written permission.
625 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
626 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
627 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
628 */
629
630
631 #include <argus/extract.h>
632
633 #include <stdio.h>
634 #include <string.h>
635
636
637 /*
638 * Convert a token value to a string; use "fmt" if not found.
639 const char *
640 tok2str(const struct tok *lp, const char *fmt, int v)
641 {
642 static char buf[128];
643
644 while (lp->s != NULL) {
645 if (lp->v == v)
646 return (lp->s);
647 ++lp;
648 }
649 if (fmt == NULL)
650 fmt = "#%d";
651 (void)snprintf(buf, sizeof(buf), fmt, v);
652 return (buf);
653 }
654 */
655
656 /*
657 * Convert a token value to a string; use "fmt" if not found.
658 */
659
660 const char *
tok2strbuf(register const struct tok * lp,register const char * fmt,register int v,char * buf,size_t bufsize)661 tok2strbuf(register const struct tok *lp, register const char *fmt,
662 register int v, char *buf, size_t bufsize)
663 {
664 if (lp != NULL) {
665 while (lp->s != NULL) {
666 if (lp->v == v)
667 return (lp->s);
668 ++lp;
669 }
670 }
671 if (fmt == NULL)
672 fmt = "#%d";
673
674 (void)snprintf(buf, bufsize, fmt, v);
675 return (const char *)buf;
676 }
677
678 /*
679 * Convert a 32-bit netmask to prefixlen if possible
680 * the function returns the prefix-len; if plen == -1
681 * then conversion was not possible;
682 */
683 int mask2plen (u_int32_t);
684
685 int
mask2plen(u_int32_t mask)686 mask2plen (u_int32_t mask)
687 {
688 u_int32_t bitmasks[33] = {
689 0x00000000,
690 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
691 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
692 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
693 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
694 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
695 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
696 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
697 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
698 };
699 int prefix_len = 32;
700
701 /* let's see if we can transform the mask into a prefixlen */
702 while (prefix_len >= 0) {
703 if (bitmasks[prefix_len] == mask)
704 break;
705 prefix_len--;
706 }
707 return (prefix_len);
708 }
709
710