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