source: rtems-libbsd/freebsd/contrib/tcpdump/print-radius.c @ d315955

5
Last change on this file since d315955 was 18fa92c, checked in by Sebastian Huber <sebastian.huber@…>, on 08/20/18 at 13:53:03

Update to FreeBSD head 2018-02-01

Git mirror commit d079ae0442af8fa3cfd6d7ede190d04e64a2c0d4.

Update #3472.

  • Property mode set to 100644
File size: 35.3 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3#ifdef __rtems__
4#include <machine/rtems-bsd-program.h>
5#include "rtems-bsd-tcpdump-namespace.h"
6#endif /* __rtems__ */
7/*
8 * Copyright (C) 2000 Alfredo Andres Omella.  All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 *   1. Redistributions of source code must retain the above copyright
15 *      notice, this list of conditions and the following disclaimer.
16 *   2. Redistributions in binary form must reproduce the above copyright
17 *      notice, this list of conditions and the following disclaimer in
18 *      the documentation and/or other materials provided with the
19 *      distribution.
20 *   3. The names of the authors may not be used to endorse or promote
21 *      products derived from this software without specific prior
22 *      written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 */
28
29/* \summary: Radius protocol printer */
30
31/*
32 * Radius printer routines as specified on:
33 *
34 * RFC 2865:
35 *      "Remote Authentication Dial In User Service (RADIUS)"
36 *
37 * RFC 2866:
38 *      "RADIUS Accounting"
39 *
40 * RFC 2867:
41 *      "RADIUS Accounting Modifications for Tunnel Protocol Support"
42 *
43 * RFC 2868:
44 *      "RADIUS Attributes for Tunnel Protocol Support"
45 *
46 * RFC 2869:
47 *      "RADIUS Extensions"
48 *
49 * RFC 3580:
50 *      "IEEE 802.1X Remote Authentication Dial In User Service (RADIUS)"
51 *      "Usage Guidelines"
52 *
53 * RFC 4675:
54 *      "RADIUS Attributes for Virtual LAN and Priority Support"
55 *
56 * RFC 5176:
57 *      "Dynamic Authorization Extensions to RADIUS"
58 *
59 * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15
60 *
61 * TODO: Among other things to print ok MacIntosh and Vendor values
62 */
63
64#ifdef HAVE_CONFIG_H
65#include "config.h"
66#endif
67
68#include <netdissect-stdinc.h>
69
70#include <string.h>
71
72#include "netdissect.h"
73#include "addrtoname.h"
74#include "extract.h"
75#include "oui.h"
76
77static const char tstr[] = " [|radius]";
78
79#define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) )
80
81#define PRINT_HEX(bytes_len, ptr_data)                               \
82           while(bytes_len)                                          \
83           {                                                         \
84              ND_PRINT((ndo, "%02X", *ptr_data ));                   \
85              ptr_data++;                                            \
86              bytes_len--;                                           \
87           }
88
89
90/* Radius packet codes */
91#define RADCMD_ACCESS_REQ   1 /* Access-Request      */
92#define RADCMD_ACCESS_ACC   2 /* Access-Accept       */
93#define RADCMD_ACCESS_REJ   3 /* Access-Reject       */
94#define RADCMD_ACCOUN_REQ   4 /* Accounting-Request  */
95#define RADCMD_ACCOUN_RES   5 /* Accounting-Response */
96#define RADCMD_ACCESS_CHA  11 /* Access-Challenge    */
97#define RADCMD_STATUS_SER  12 /* Status-Server       */
98#define RADCMD_STATUS_CLI  13 /* Status-Client       */
99#define RADCMD_DISCON_REQ  40 /* Disconnect-Request  */
100#define RADCMD_DISCON_ACK  41 /* Disconnect-ACK      */
101#define RADCMD_DISCON_NAK  42 /* Disconnect-NAK      */
102#define RADCMD_COA_REQ     43 /* CoA-Request         */
103#define RADCMD_COA_ACK     44 /* CoA-ACK             */
104#define RADCMD_COA_NAK     45 /* CoA-NAK             */
105#define RADCMD_RESERVED   255 /* Reserved            */
106
107static const struct tok radius_command_values[] = {
108    { RADCMD_ACCESS_REQ, "Access-Request" },
109    { RADCMD_ACCESS_ACC, "Access-Accept" },
110    { RADCMD_ACCESS_REJ, "Access-Reject" },
111    { RADCMD_ACCOUN_REQ, "Accounting-Request" },
112    { RADCMD_ACCOUN_RES, "Accounting-Response" },
113    { RADCMD_ACCESS_CHA, "Access-Challenge" },
114    { RADCMD_STATUS_SER, "Status-Server" },
115    { RADCMD_STATUS_CLI, "Status-Client" },
116    { RADCMD_DISCON_REQ, "Disconnect-Request" },
117    { RADCMD_DISCON_ACK, "Disconnect-ACK" },
118    { RADCMD_DISCON_NAK, "Disconnect-NAK" },
119    { RADCMD_COA_REQ,    "CoA-Request" },
120    { RADCMD_COA_ACK,    "CoA-ACK" },
121    { RADCMD_COA_NAK,    "CoA-NAK" },
122    { RADCMD_RESERVED,   "Reserved" },
123    { 0, NULL}
124};
125
126/********************************/
127/* Begin Radius Attribute types */
128/********************************/
129#define SERV_TYPE    6
130#define FRM_IPADDR   8
131#define LOG_IPHOST  14
132#define LOG_SERVICE 15
133#define FRM_IPX     23
134#define SESSION_TIMEOUT   27
135#define IDLE_TIMEOUT      28
136#define FRM_ATALK_LINK    37
137#define FRM_ATALK_NETWORK 38
138
139#define ACCT_DELAY        41
140#define ACCT_SESSION_TIME 46
141
142#define EGRESS_VLAN_ID   56
143#define EGRESS_VLAN_NAME 58
144
145#define TUNNEL_TYPE        64
146#define TUNNEL_MEDIUM      65
147#define TUNNEL_CLIENT_END  66
148#define TUNNEL_SERVER_END  67
149#define TUNNEL_PASS        69
150
151#define ARAP_PASS          70
152#define ARAP_FEATURES      71
153
154#define TUNNEL_PRIV_GROUP  81
155#define TUNNEL_ASSIGN_ID   82
156#define TUNNEL_PREFERENCE  83
157
158#define ARAP_CHALLENGE_RESP 84
159#define ACCT_INT_INTERVAL   85
160
161#define TUNNEL_CLIENT_AUTH 90
162#define TUNNEL_SERVER_AUTH 91
163/********************************/
164/* End Radius Attribute types */
165/********************************/
166
167#define RFC4675_TAGGED   0x31
168#define RFC4675_UNTAGGED 0x32
169
170static const struct tok rfc4675_tagged[] = {
171    { RFC4675_TAGGED,   "Tagged" },
172    { RFC4675_UNTAGGED, "Untagged" },
173    { 0, NULL}
174};
175
176
177static void print_attr_string(netdissect_options *, register const u_char *, u_int, u_short );
178static void print_attr_num(netdissect_options *, register const u_char *, u_int, u_short );
179static void print_vendor_attr(netdissect_options *, register const u_char *, u_int, u_short );
180static void print_attr_address(netdissect_options *, register const u_char *, u_int, u_short);
181static void print_attr_time(netdissect_options *, register const u_char *, u_int, u_short);
182static void print_attr_strange(netdissect_options *, register const u_char *, u_int, u_short);
183
184
185struct radius_hdr { uint8_t  code; /* Radius packet code  */
186                    uint8_t  id;   /* Radius packet id    */
187                    uint16_t len;  /* Radius total length */
188                    uint8_t  auth[16]; /* Authenticator   */
189                  };
190
191#define MIN_RADIUS_LEN  20
192
193struct radius_attr { uint8_t type; /* Attribute type   */
194                     uint8_t len;  /* Attribute length */
195                   };
196
197
198/* Service-Type Attribute standard values */
199static const char *serv_type[]={ NULL,
200                                "Login",
201                                "Framed",
202                                "Callback Login",
203                                "Callback Framed",
204                                "Outbound",
205                                "Administrative",
206                                "NAS Prompt",
207                                "Authenticate Only",
208                                "Callback NAS Prompt",
209                                "Call Check",
210                                "Callback Administrative",
211                               };
212
213/* Framed-Protocol Attribute standard values */
214static const char *frm_proto[]={ NULL,
215                                 "PPP",
216                                 "SLIP",
217                                 "ARAP",
218                                 "Gandalf proprietary",
219                                 "Xylogics IPX/SLIP",
220                                 "X.75 Synchronous",
221                               };
222
223/* Framed-Routing Attribute standard values */
224static const char *frm_routing[]={ "None",
225                                   "Send",
226                                   "Listen",
227                                   "Send&Listen",
228                                 };
229
230/* Framed-Compression Attribute standard values */
231static const char *frm_comp[]={ "None",
232                                "VJ TCP/IP",
233                                "IPX",
234                                "Stac-LZS",
235                              };
236
237/* Login-Service Attribute standard values */
238static const char *login_serv[]={ "Telnet",
239                                  "Rlogin",
240                                  "TCP Clear",
241                                  "PortMaster(proprietary)",
242                                  "LAT",
243                                  "X.25-PAD",
244                                  "X.25-T3POS",
245                                  "Unassigned",
246                                  "TCP Clear Quiet",
247                                };
248
249
250/* Termination-Action Attribute standard values */
251static const char *term_action[]={ "Default",
252                                   "RADIUS-Request",
253                                 };
254
255/* Ingress-Filters Attribute standard values */
256static const char *ingress_filters[]={ NULL,
257                                       "Enabled",
258                                       "Disabled",
259                                     };
260
261/* NAS-Port-Type Attribute standard values */
262static const char *nas_port_type[]={ "Async",
263                                     "Sync",
264                                     "ISDN Sync",
265                                     "ISDN Async V.120",
266                                     "ISDN Async V.110",
267                                     "Virtual",
268                                     "PIAFS",
269                                     "HDLC Clear Channel",
270                                     "X.25",
271                                     "X.75",
272                                     "G.3 Fax",
273                                     "SDSL",
274                                     "ADSL-CAP",
275                                     "ADSL-DMT",
276                                     "ISDN-DSL",
277                                     "Ethernet",
278                                     "xDSL",
279                                     "Cable",
280                                     "Wireless - Other",
281                                     "Wireless - IEEE 802.11",
282                                   };
283
284/* Acct-Status-Type Accounting Attribute standard values */
285static const char *acct_status[]={ NULL,
286                                   "Start",
287                                   "Stop",
288                                   "Interim-Update",
289                                   "Unassigned",
290                                   "Unassigned",
291                                   "Unassigned",
292                                   "Accounting-On",
293                                   "Accounting-Off",
294                                   "Tunnel-Start",
295                                   "Tunnel-Stop",
296                                   "Tunnel-Reject",
297                                   "Tunnel-Link-Start",
298                                   "Tunnel-Link-Stop",
299                                   "Tunnel-Link-Reject",
300                                   "Failed",
301                                 };
302
303/* Acct-Authentic Accounting Attribute standard values */
304static const char *acct_auth[]={ NULL,
305                                 "RADIUS",
306                                 "Local",
307                                 "Remote",
308                               };
309
310/* Acct-Terminate-Cause Accounting Attribute standard values */
311static const char *acct_term[]={ NULL,
312                                 "User Request",
313                                 "Lost Carrier",
314                                 "Lost Service",
315                                 "Idle Timeout",
316                                 "Session Timeout",
317                                 "Admin Reset",
318                                 "Admin Reboot",
319                                 "Port Error",
320                                 "NAS Error",
321                                 "NAS Request",
322                                 "NAS Reboot",
323                                 "Port Unneeded",
324                                 "Port Preempted",
325                                 "Port Suspended",
326                                 "Service Unavailable",
327                                 "Callback",
328                                 "User Error",
329                                 "Host Request",
330                               };
331
332/* Tunnel-Type Attribute standard values */
333static const char *tunnel_type[]={ NULL,
334                                   "PPTP",
335                                   "L2F",
336                                   "L2TP",
337                                   "ATMP",
338                                   "VTP",
339                                   "AH",
340                                   "IP-IP",
341                                   "MIN-IP-IP",
342                                   "ESP",
343                                   "GRE",
344                                   "DVS",
345                                   "IP-in-IP Tunneling",
346                                   "VLAN",
347                                 };
348
349/* Tunnel-Medium-Type Attribute standard values */
350static const char *tunnel_medium[]={ NULL,
351                                     "IPv4",
352                                     "IPv6",
353                                     "NSAP",
354                                     "HDLC",
355                                     "BBN 1822",
356                                     "802",
357                                     "E.163",
358                                     "E.164",
359                                     "F.69",
360                                     "X.121",
361                                     "IPX",
362                                     "Appletalk",
363                                     "Decnet IV",
364                                     "Banyan Vines",
365                                     "E.164 with NSAP subaddress",
366                                   };
367
368/* ARAP-Zone-Access Attribute standard values */
369static const char *arap_zone[]={ NULL,
370                                 "Only access to dfl zone",
371                                 "Use zone filter inc.",
372                                 "Not used",
373                                 "Use zone filter exc.",
374                               };
375
376static const char *prompt[]={ "No Echo",
377                              "Echo",
378                            };
379
380
381static struct attrtype {
382                  const char *name;      /* Attribute name                 */
383                  const char **subtypes; /* Standard Values (if any)       */
384                  u_char siz_subtypes;   /* Size of total standard values  */
385                  u_char first_subtype;  /* First standard value is 0 or 1 */
386                  void (*print_func)(netdissect_options *, register const u_char *, u_int, u_short);
387                } attr_type[]=
388  {
389     { NULL,                              NULL, 0, 0, NULL               },
390     { "User-Name",                       NULL, 0, 0, print_attr_string  },
391     { "User-Password",                   NULL, 0, 0, NULL               },
392     { "CHAP-Password",                   NULL, 0, 0, NULL               },
393     { "NAS-IP-Address",                  NULL, 0, 0, print_attr_address },
394     { "NAS-Port",                        NULL, 0, 0, print_attr_num     },
395     { "Service-Type",                    serv_type, TAM_SIZE(serv_type)-1, 1, print_attr_num },
396     { "Framed-Protocol",                 frm_proto, TAM_SIZE(frm_proto)-1, 1, print_attr_num },
397     { "Framed-IP-Address",               NULL, 0, 0, print_attr_address },
398     { "Framed-IP-Netmask",               NULL, 0, 0, print_attr_address },
399     { "Framed-Routing",                  frm_routing, TAM_SIZE(frm_routing), 0, print_attr_num },
400     { "Filter-Id",                       NULL, 0, 0, print_attr_string  },
401     { "Framed-MTU",                      NULL, 0, 0, print_attr_num     },
402     { "Framed-Compression",              frm_comp, TAM_SIZE(frm_comp),   0, print_attr_num },
403     { "Login-IP-Host",                   NULL, 0, 0, print_attr_address },
404     { "Login-Service",                   login_serv, TAM_SIZE(login_serv), 0, print_attr_num },
405     { "Login-TCP-Port",                  NULL, 0, 0, print_attr_num     },
406     { "Unassigned",                      NULL, 0, 0, NULL }, /*17*/
407     { "Reply-Message",                   NULL, 0, 0, print_attr_string },
408     { "Callback-Number",                 NULL, 0, 0, print_attr_string },
409     { "Callback-Id",                     NULL, 0, 0, print_attr_string },
410     { "Unassigned",                      NULL, 0, 0, NULL }, /*21*/
411     { "Framed-Route",                    NULL, 0, 0, print_attr_string },
412     { "Framed-IPX-Network",              NULL, 0, 0, print_attr_num    },
413     { "State",                           NULL, 0, 0, print_attr_string },
414     { "Class",                           NULL, 0, 0, print_attr_string },
415     { "Vendor-Specific",                 NULL, 0, 0, print_vendor_attr },
416     { "Session-Timeout",                 NULL, 0, 0, print_attr_num    },
417     { "Idle-Timeout",                    NULL, 0, 0, print_attr_num    },
418     { "Termination-Action",              term_action, TAM_SIZE(term_action), 0, print_attr_num },
419     { "Called-Station-Id",               NULL, 0, 0, print_attr_string },
420     { "Calling-Station-Id",              NULL, 0, 0, print_attr_string },
421     { "NAS-Identifier",                  NULL, 0, 0, print_attr_string },
422     { "Proxy-State",                     NULL, 0, 0, print_attr_string },
423     { "Login-LAT-Service",               NULL, 0, 0, print_attr_string },
424     { "Login-LAT-Node",                  NULL, 0, 0, print_attr_string },
425     { "Login-LAT-Group",                 NULL, 0, 0, print_attr_string },
426     { "Framed-AppleTalk-Link",           NULL, 0, 0, print_attr_num    },
427     { "Framed-AppleTalk-Network",        NULL, 0, 0, print_attr_num    },
428     { "Framed-AppleTalk-Zone",           NULL, 0, 0, print_attr_string },
429     { "Acct-Status-Type",                acct_status, TAM_SIZE(acct_status)-1, 1, print_attr_num },
430     { "Acct-Delay-Time",                 NULL, 0, 0, print_attr_num    },
431     { "Acct-Input-Octets",               NULL, 0, 0, print_attr_num    },
432     { "Acct-Output-Octets",              NULL, 0, 0, print_attr_num    },
433     { "Acct-Session-Id",                 NULL, 0, 0, print_attr_string },
434     { "Acct-Authentic",                  acct_auth, TAM_SIZE(acct_auth)-1, 1, print_attr_num },
435     { "Acct-Session-Time",               NULL, 0, 0, print_attr_num },
436     { "Acct-Input-Packets",              NULL, 0, 0, print_attr_num },
437     { "Acct-Output-Packets",             NULL, 0, 0, print_attr_num },
438     { "Acct-Terminate-Cause",            acct_term, TAM_SIZE(acct_term)-1, 1, print_attr_num },
439     { "Acct-Multi-Session-Id",           NULL, 0, 0, print_attr_string },
440     { "Acct-Link-Count",                 NULL, 0, 0, print_attr_num },
441     { "Acct-Input-Gigawords",            NULL, 0, 0, print_attr_num },
442     { "Acct-Output-Gigawords",           NULL, 0, 0, print_attr_num },
443     { "Unassigned",                      NULL, 0, 0, NULL }, /*54*/
444     { "Event-Timestamp",                 NULL, 0, 0, print_attr_time },
445     { "Egress-VLANID",                   NULL, 0, 0, print_attr_num },
446     { "Ingress-Filters",                 ingress_filters, TAM_SIZE(ingress_filters)-1, 1, print_attr_num },
447     { "Egress-VLAN-Name",                NULL, 0, 0, print_attr_string },
448     { "User-Priority-Table",             NULL, 0, 0, NULL },
449     { "CHAP-Challenge",                  NULL, 0, 0, print_attr_string },
450     { "NAS-Port-Type",                   nas_port_type, TAM_SIZE(nas_port_type), 0, print_attr_num },
451     { "Port-Limit",                      NULL, 0, 0, print_attr_num },
452     { "Login-LAT-Port",                  NULL, 0, 0, print_attr_string }, /*63*/
453     { "Tunnel-Type",                     tunnel_type, TAM_SIZE(tunnel_type)-1, 1, print_attr_num },
454     { "Tunnel-Medium-Type",              tunnel_medium, TAM_SIZE(tunnel_medium)-1, 1, print_attr_num },
455     { "Tunnel-Client-Endpoint",          NULL, 0, 0, print_attr_string },
456     { "Tunnel-Server-Endpoint",          NULL, 0, 0, print_attr_string },
457     { "Acct-Tunnel-Connection",          NULL, 0, 0, print_attr_string },
458     { "Tunnel-Password",                 NULL, 0, 0, print_attr_string  },
459     { "ARAP-Password",                   NULL, 0, 0, print_attr_strange },
460     { "ARAP-Features",                   NULL, 0, 0, print_attr_strange },
461     { "ARAP-Zone-Access",                arap_zone, TAM_SIZE(arap_zone)-1, 1, print_attr_num }, /*72*/
462     { "ARAP-Security",                   NULL, 0, 0, print_attr_string },
463     { "ARAP-Security-Data",              NULL, 0, 0, print_attr_string },
464     { "Password-Retry",                  NULL, 0, 0, print_attr_num    },
465     { "Prompt",                          prompt, TAM_SIZE(prompt), 0, print_attr_num },
466     { "Connect-Info",                    NULL, 0, 0, print_attr_string   },
467     { "Configuration-Token",             NULL, 0, 0, print_attr_string   },
468     { "EAP-Message",                     NULL, 0, 0, print_attr_string   },
469     { "Message-Authenticator",           NULL, 0, 0, print_attr_string }, /*80*/
470     { "Tunnel-Private-Group-ID",         NULL, 0, 0, print_attr_string },
471     { "Tunnel-Assignment-ID",            NULL, 0, 0, print_attr_string },
472     { "Tunnel-Preference",               NULL, 0, 0, print_attr_num    },
473     { "ARAP-Challenge-Response",         NULL, 0, 0, print_attr_strange },
474     { "Acct-Interim-Interval",           NULL, 0, 0, print_attr_num     },
475     { "Acct-Tunnel-Packets-Lost",        NULL, 0, 0, print_attr_num }, /*86*/
476     { "NAS-Port-Id",                     NULL, 0, 0, print_attr_string },
477     { "Framed-Pool",                     NULL, 0, 0, print_attr_string },
478     { "CUI",                             NULL, 0, 0, print_attr_string },
479     { "Tunnel-Client-Auth-ID",           NULL, 0, 0, print_attr_string },
480     { "Tunnel-Server-Auth-ID",           NULL, 0, 0, print_attr_string },
481     { "Unassigned",                      NULL, 0, 0, NULL }, /*92*/
482     { "Unassigned",                      NULL, 0, 0, NULL }  /*93*/
483  };
484
485
486/*****************************/
487/* Print an attribute string */
488/* value pointed by 'data'   */
489/* and 'length' size.        */
490/*****************************/
491/* Returns nothing.          */
492/*****************************/
493static void
494print_attr_string(netdissect_options *ndo,
495                  register const u_char *data, u_int length, u_short attr_code)
496{
497   register u_int i;
498
499   ND_TCHECK2(data[0],length);
500
501   switch(attr_code)
502   {
503      case TUNNEL_PASS:
504           if (length < 3)
505              goto trunc;
506           if (*data && (*data <=0x1F) )
507              ND_PRINT((ndo, "Tag[%u] ", *data));
508           else
509              ND_PRINT((ndo, "Tag[Unused] "));
510           data++;
511           length--;
512           ND_PRINT((ndo, "Salt %u ", EXTRACT_16BITS(data)));
513           data+=2;
514           length-=2;
515        break;
516      case TUNNEL_CLIENT_END:
517      case TUNNEL_SERVER_END:
518      case TUNNEL_PRIV_GROUP:
519      case TUNNEL_ASSIGN_ID:
520      case TUNNEL_CLIENT_AUTH:
521      case TUNNEL_SERVER_AUTH:
522           if (*data <= 0x1F)
523           {
524              if (length < 1)
525                 goto trunc;
526              if (*data)
527                ND_PRINT((ndo, "Tag[%u] ", *data));
528              else
529                ND_PRINT((ndo, "Tag[Unused] "));
530              data++;
531              length--;
532           }
533        break;
534      case EGRESS_VLAN_NAME:
535           if (length < 1)
536              goto trunc;
537           ND_PRINT((ndo, "%s (0x%02x) ",
538                  tok2str(rfc4675_tagged,"Unknown tag",*data),
539                  *data));
540           data++;
541           length--;
542        break;
543   }
544
545   for (i=0; i < length && *data; i++, data++)
546       ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data));
547
548   return;
549
550   trunc:
551      ND_PRINT((ndo, "%s", tstr));
552}
553
554/*
555 * print vendor specific attributes
556 */
557static void
558print_vendor_attr(netdissect_options *ndo,
559                  register const u_char *data, u_int length, u_short attr_code _U_)
560{
561    u_int idx;
562    u_int vendor_id;
563    u_int vendor_type;
564    u_int vendor_length;
565
566    if (length < 4)
567        goto trunc;
568    ND_TCHECK2(*data, 4);
569    vendor_id = EXTRACT_32BITS(data);
570    data+=4;
571    length-=4;
572
573    ND_PRINT((ndo, "Vendor: %s (%u)",
574           tok2str(smi_values,"Unknown",vendor_id),
575           vendor_id));
576
577    while (length >= 2) {
578        ND_TCHECK2(*data, 2);
579
580        vendor_type = *(data);
581        vendor_length = *(data+1);
582
583        if (vendor_length < 2)
584        {
585            ND_PRINT((ndo, "\n\t    Vendor Attribute: %u, Length: %u (bogus, must be >= 2)",
586                   vendor_type,
587                   vendor_length));
588            return;
589        }
590        if (vendor_length > length)
591        {
592            ND_PRINT((ndo, "\n\t    Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)",
593                   vendor_type,
594                   vendor_length));
595            return;
596        }
597        data+=2;
598        vendor_length-=2;
599        length-=2;
600        ND_TCHECK2(*data, vendor_length);
601
602        ND_PRINT((ndo, "\n\t    Vendor Attribute: %u, Length: %u, Value: ",
603               vendor_type,
604               vendor_length));
605        for (idx = 0; idx < vendor_length ; idx++, data++)
606            ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data));
607        length-=vendor_length;
608    }
609    return;
610
611   trunc:
612     ND_PRINT((ndo, "%s", tstr));
613}
614
615/******************************/
616/* Print an attribute numeric */
617/* value pointed by 'data'    */
618/* and 'length' size.         */
619/******************************/
620/* Returns nothing.           */
621/******************************/
622static void
623print_attr_num(netdissect_options *ndo,
624               register const u_char *data, u_int length, u_short attr_code)
625{
626   uint32_t timeout;
627
628   if (length != 4)
629   {
630       ND_PRINT((ndo, "ERROR: length %u != 4", length));
631       return;
632   }
633
634   ND_TCHECK2(data[0],4);
635                          /* This attribute has standard values */
636   if (attr_type[attr_code].siz_subtypes)
637   {
638      static const char **table;
639      uint32_t data_value;
640      table = attr_type[attr_code].subtypes;
641
642      if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) )
643      {
644         if (!*data)
645            ND_PRINT((ndo, "Tag[Unused] "));
646         else
647            ND_PRINT((ndo, "Tag[%d] ", *data));
648         data++;
649         data_value = EXTRACT_24BITS(data);
650      }
651      else
652      {
653         data_value = EXTRACT_32BITS(data);
654      }
655      if ( data_value <= (uint32_t)(attr_type[attr_code].siz_subtypes - 1 +
656            attr_type[attr_code].first_subtype) &&
657           data_value >= attr_type[attr_code].first_subtype )
658         ND_PRINT((ndo, "%s", table[data_value]));
659      else
660         ND_PRINT((ndo, "#%u", data_value));
661   }
662   else
663   {
664      switch(attr_code) /* Be aware of special cases... */
665      {
666        case FRM_IPX:
667             if (EXTRACT_32BITS( data) == 0xFFFFFFFE )
668                ND_PRINT((ndo, "NAS Select"));
669             else
670                ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
671          break;
672
673        case SESSION_TIMEOUT:
674        case IDLE_TIMEOUT:
675        case ACCT_DELAY:
676        case ACCT_SESSION_TIME:
677        case ACCT_INT_INTERVAL:
678             timeout = EXTRACT_32BITS( data);
679             if ( timeout < 60 )
680                ND_PRINT((ndo,  "%02d secs", timeout));
681             else
682             {
683                if ( timeout < 3600 )
684                   ND_PRINT((ndo,  "%02d:%02d min",
685                          timeout / 60, timeout % 60));
686                else
687                   ND_PRINT((ndo, "%02d:%02d:%02d hours",
688                          timeout / 3600, (timeout % 3600) / 60,
689                          timeout % 60));
690             }
691          break;
692
693        case FRM_ATALK_LINK:
694             if (EXTRACT_32BITS(data) )
695                ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
696             else
697                ND_PRINT((ndo, "Unnumbered"));
698          break;
699
700        case FRM_ATALK_NETWORK:
701             if (EXTRACT_32BITS(data) )
702                ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
703             else
704                ND_PRINT((ndo, "NAS assigned"));
705          break;
706
707        case TUNNEL_PREFERENCE:
708            if (*data)
709               ND_PRINT((ndo, "Tag[%d] ", *data));
710            else
711               ND_PRINT((ndo, "Tag[Unused] "));
712            data++;
713            ND_PRINT((ndo, "%d", EXTRACT_24BITS(data)));
714          break;
715
716        case EGRESS_VLAN_ID:
717            ND_PRINT((ndo, "%s (0x%02x) ",
718                   tok2str(rfc4675_tagged,"Unknown tag",*data),
719                   *data));
720            data++;
721            ND_PRINT((ndo, "%d", EXTRACT_24BITS(data)));
722          break;
723
724        default:
725             ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
726          break;
727
728      } /* switch */
729
730   } /* if-else */
731
732   return;
733
734   trunc:
735     ND_PRINT((ndo, "%s", tstr));
736}
737
738/*****************************/
739/* Print an attribute IPv4   */
740/* address value pointed by  */
741/* 'data' and 'length' size. */
742/*****************************/
743/* Returns nothing.          */
744/*****************************/
745static void
746print_attr_address(netdissect_options *ndo,
747                   register const u_char *data, u_int length, u_short attr_code)
748{
749   if (length != 4)
750   {
751       ND_PRINT((ndo, "ERROR: length %u != 4", length));
752       return;
753   }
754
755   ND_TCHECK2(data[0],4);
756
757   switch(attr_code)
758   {
759      case FRM_IPADDR:
760      case LOG_IPHOST:
761           if (EXTRACT_32BITS(data) == 0xFFFFFFFF )
762              ND_PRINT((ndo, "User Selected"));
763           else
764              if (EXTRACT_32BITS(data) == 0xFFFFFFFE )
765                 ND_PRINT((ndo, "NAS Select"));
766              else
767                 ND_PRINT((ndo, "%s",ipaddr_string(ndo, data)));
768      break;
769
770      default:
771          ND_PRINT((ndo, "%s", ipaddr_string(ndo, data)));
772      break;
773   }
774
775   return;
776
777   trunc:
778     ND_PRINT((ndo, "%s", tstr));
779}
780
781/*************************************/
782/* Print an attribute of 'secs since */
783/* January 1, 1970 00:00 UTC' value  */
784/* pointed by 'data' and 'length'    */
785/* size.                             */
786/*************************************/
787/* Returns nothing.                  */
788/*************************************/
789static void
790print_attr_time(netdissect_options *ndo,
791                register const u_char *data, u_int length, u_short attr_code _U_)
792{
793   time_t attr_time;
794   char string[26];
795
796   if (length != 4)
797   {
798       ND_PRINT((ndo, "ERROR: length %u != 4", length));
799       return;
800   }
801
802   ND_TCHECK2(data[0],4);
803
804   attr_time = EXTRACT_32BITS(data);
805   strlcpy(string, ctime(&attr_time), sizeof(string));
806   /* Get rid of the newline */
807   string[24] = '\0';
808   ND_PRINT((ndo, "%.24s", string));
809   return;
810
811   trunc:
812     ND_PRINT((ndo, "%s", tstr));
813}
814
815/***********************************/
816/* Print an attribute of 'strange' */
817/* data format pointed by 'data'   */
818/* and 'length' size.              */
819/***********************************/
820/* Returns nothing.                */
821/***********************************/
822static void
823print_attr_strange(netdissect_options *ndo,
824                   register const u_char *data, u_int length, u_short attr_code)
825{
826   u_short len_data;
827
828   switch(attr_code)
829   {
830      case ARAP_PASS:
831           if (length != 16)
832           {
833               ND_PRINT((ndo, "ERROR: length %u != 16", length));
834               return;
835           }
836           ND_PRINT((ndo, "User_challenge ("));
837           ND_TCHECK2(data[0],8);
838           len_data = 8;
839           PRINT_HEX(len_data, data);
840           ND_PRINT((ndo, ") User_resp("));
841           ND_TCHECK2(data[0],8);
842           len_data = 8;
843           PRINT_HEX(len_data, data);
844           ND_PRINT((ndo, ")"));
845        break;
846
847      case ARAP_FEATURES:
848           if (length != 14)
849           {
850               ND_PRINT((ndo, "ERROR: length %u != 14", length));
851               return;
852           }
853           ND_TCHECK2(data[0],1);
854           if (*data)
855              ND_PRINT((ndo, "User can change password"));
856           else
857              ND_PRINT((ndo, "User cannot change password"));
858           data++;
859           ND_TCHECK2(data[0],1);
860           ND_PRINT((ndo, ", Min password length: %d", *data));
861           data++;
862           ND_PRINT((ndo, ", created at: "));
863           ND_TCHECK2(data[0],4);
864           len_data = 4;
865           PRINT_HEX(len_data, data);
866           ND_PRINT((ndo, ", expires in: "));
867           ND_TCHECK2(data[0],4);
868           len_data = 4;
869           PRINT_HEX(len_data, data);
870           ND_PRINT((ndo, ", Current Time: "));
871           ND_TCHECK2(data[0],4);
872           len_data = 4;
873           PRINT_HEX(len_data, data);
874        break;
875
876      case ARAP_CHALLENGE_RESP:
877           if (length < 8)
878           {
879               ND_PRINT((ndo, "ERROR: length %u != 8", length));
880               return;
881           }
882           ND_TCHECK2(data[0],8);
883           len_data = 8;
884           PRINT_HEX(len_data, data);
885        break;
886   }
887   return;
888
889   trunc:
890     ND_PRINT((ndo, "%s", tstr));
891}
892
893static void
894radius_attrs_print(netdissect_options *ndo,
895                   register const u_char *attr, u_int length)
896{
897   register const struct radius_attr *rad_attr = (const struct radius_attr *)attr;
898   const char *attr_string;
899
900   while (length > 0)
901   {
902     if (length < 2)
903        goto trunc;
904     ND_TCHECK(*rad_attr);
905
906     if (rad_attr->type > 0 && rad_attr->type < TAM_SIZE(attr_type))
907        attr_string = attr_type[rad_attr->type].name;
908     else
909        attr_string = "Unknown";
910     if (rad_attr->len < 2)
911     {
912        ND_PRINT((ndo, "\n\t  %s Attribute (%u), length: %u (bogus, must be >= 2)",
913               attr_string,
914               rad_attr->type,
915               rad_attr->len));
916        return;
917     }
918     if (rad_attr->len > length)
919     {
920        ND_PRINT((ndo, "\n\t  %s Attribute (%u), length: %u (bogus, goes past end of packet)",
921               attr_string,
922               rad_attr->type,
923               rad_attr->len));
924        return;
925     }
926     ND_PRINT((ndo, "\n\t  %s Attribute (%u), length: %u, Value: ",
927            attr_string,
928            rad_attr->type,
929            rad_attr->len));
930
931     if (rad_attr->type < TAM_SIZE(attr_type))
932     {
933         if (rad_attr->len > 2)
934         {
935             if ( attr_type[rad_attr->type].print_func )
936                 (*attr_type[rad_attr->type].print_func)(
937                     ndo, ((const u_char *)(rad_attr+1)),
938                     rad_attr->len - 2, rad_attr->type);
939         }
940     }
941     /* do we also want to see a hex dump ? */
942     if (ndo->ndo_vflag> 1)
943         print_unknown_data(ndo, (const u_char *)rad_attr+2, "\n\t    ", (rad_attr->len)-2);
944
945     length-=(rad_attr->len);
946     rad_attr = (const struct radius_attr *)( ((const char *)(rad_attr))+rad_attr->len);
947   }
948   return;
949
950trunc:
951   ND_PRINT((ndo, "%s", tstr));
952}
953
954void
955radius_print(netdissect_options *ndo,
956             const u_char *dat, u_int length)
957{
958   register const struct radius_hdr *rad;
959   u_int len, auth_idx;
960
961   ND_TCHECK2(*dat, MIN_RADIUS_LEN);
962   rad = (const struct radius_hdr *)dat;
963   len = EXTRACT_16BITS(&rad->len);
964
965   if (len < MIN_RADIUS_LEN)
966   {
967          ND_PRINT((ndo, "%s", tstr));
968          return;
969   }
970
971   if (len > length)
972          len = length;
973
974   if (ndo->ndo_vflag < 1) {
975       ND_PRINT((ndo, "RADIUS, %s (%u), id: 0x%02x length: %u",
976              tok2str(radius_command_values,"Unknown Command",rad->code),
977              rad->code,
978              rad->id,
979              len));
980       return;
981   }
982   else {
983       ND_PRINT((ndo, "RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ",
984              len,
985              tok2str(radius_command_values,"Unknown Command",rad->code),
986              rad->code,
987              rad->id));
988
989       for(auth_idx=0; auth_idx < 16; auth_idx++)
990            ND_PRINT((ndo, "%02x", rad->auth[auth_idx]));
991   }
992
993   if (len > MIN_RADIUS_LEN)
994      radius_attrs_print(ndo, dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN);
995   return;
996
997trunc:
998   ND_PRINT((ndo, "%s", tstr));
999}
1000#ifdef __rtems__
1001#include "rtems-bsd-tcpdump-print-radius-data.h"
1002#endif /* __rtems__ */
Note: See TracBrowser for help on using the repository browser.