]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-radius.c
When discussing the "gateway" keyword, don't say that the host must be
[tcpdump] / print-radius.c
index c27e56438bfd73d463a0d9139c5138d7f5736cfe..24d33f8e9c5032400bd1d1b966890eedd9816646 100644 (file)
  * RFC 2869:
  *      "RADIUS Extensions"
  *
- * Alfredo Andres Omella (aandres@mfom.es) v0.1 2000/09/15
+ * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15
  *
  * TODO: Among other things to print ok MacIntosh and Vendor values 
  */
 
 #ifndef lint
 static const char rcsid[] =
-    "$Id: print-radius.c,v 1.1 2000-10-06 06:49:21 guy Exp $";
+    "$Id: print-radius.c,v 1.7 2001-06-18 09:16:28 guy Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+#include <string.h>
+
 #include <sys/param.h>
-#include <sys/time.h>
-#include <sys/socket.h>
 
 #include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
 
 #include <stdio.h>
 
@@ -49,13 +44,10 @@ static const char rcsid[] =
 
 #define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) )
 
-#define HEX(a)  ((char)( (a) <= 9 ? (a) + '0' : ((a) - 10) + 'A'))
-
 #define PRINT_HEX(bytes_len, ptr_data)                               \
            while(bytes_len)                                          \
            {                                                         \
-              printf("%c%c", HEX( ((u_short)(*ptr_data)) >> 4 ),     \
-                             HEX( ((u_short)(*ptr_data)) & 0x0F ) ); \
+              printf("%02X", *ptr_data );                            \
               ptr_data++;                                            \
               bytes_len--;                                           \
            }
@@ -119,15 +111,16 @@ static void print_attr_time(register u_char *, u_int, u_short);
 static void print_attr_strange(register u_char *, u_int, u_short);
 
 
-struct radius_hdr { u_char  code; /* Radius packet code  */
-                    u_char  id;   /* Radius packet id    */
-                    u_short len;  /* Radius total length */
-                    u_char  auth[16]; /* Authenticator   */
+struct radius_hdr { u_int8_t  code; /* Radius packet code  */
+                    u_int8_t  id;   /* Radius packet id    */
+                    u_int16_t len;  /* Radius total length */
+                    u_int8_t  auth[16]; /* Authenticator   */
                   };
 
+#define MIN_RADIUS_LEN 20
 
-struct radius_attr { u_char type; /* Attribute type   */
-                     u_char len;  /* Attribute length */
+struct radius_attr { u_int8_t type; /* Attribute type   */
+                     u_int8_t len;  /* Attribute length */
                    };
 
 
@@ -477,8 +470,15 @@ print_attr_string(register u_char *data, u_int length, u_short attr_code )
 static void
 print_attr_num(register u_char *data, u_int length, u_short attr_code )
 {
+   u_int8_t tag;
    u_int32_t timeout;
    
+   if (length != 4)
+   {
+       printf("{length %u != 4}", length);
+       return;
+   }
+
    TCHECK2(data[0],4);
                           /* This attribute has standard values */
    if (attr_type[attr_code].siz_subtypes) 
@@ -493,10 +493,14 @@ print_attr_num(register u_char *data, u_int length, u_short attr_code )
             printf("{Tag[Unused]");
          else
             printf("{Tag[%d]", *data);
-         data_value = EXTRACT_24BITS(++data);
+         data++;
+         data_value = EXTRACT_24BITS(data);
       }
       else
-         data_value = EXTRACT_32BITS(++data);
+      {
+        data++;
+         data_value = EXTRACT_32BITS(data);
+      }
       if ( data_value <= (attr_type[attr_code].siz_subtypes - 1 +
             attr_type[attr_code].first_subtype) )
          printf("{%s}",table[data_value]);
@@ -549,10 +553,12 @@ print_attr_num(register u_char *data, u_int length, u_short attr_code )
           break;
 
         case TUNNEL_PREFERENCE:
-            if (!*data)
-               printf("{Tag[Unused] %d}",EXTRACT_24BITS(++data) );
+            tag = *data;
+            data++;
+            if (tag == 0)
+               printf("{Tag[Unused] %d}",EXTRACT_24BITS(data) );
             else
-               printf("{Tag[%d] %d}", *data, EXTRACT_24BITS(++data) );
+               printf("{Tag[%d] %d}", tag, EXTRACT_24BITS(data) );
           break;
 
         default:
@@ -580,6 +586,12 @@ print_attr_num(register u_char *data, u_int length, u_short attr_code )
 static void
 print_attr_address(register u_char *data, u_int length, u_short attr_code )
 {
+   if (length != 4)
+   {
+       printf("{length %u != 4}", length);
+       return;
+   }
+
    TCHECK2(data[0],4);
    
    switch(attr_code)
@@ -617,9 +629,22 @@ print_attr_address(register u_char *data, u_int length, u_short attr_code )
 /*************************************/
 static void print_attr_time(register u_char *data, u_int length, u_short attr_code)
 {
+   time_t attr_time;
+   char string[26];
+
+   if (length != 4)
+   {
+       printf("{length %u != 4}", length);
+       return;
+   }
+
    TCHECK2(data[0],4);
    
-   printf("{%s}", ctime( ((const time_t *)EXTRACT_32BITS(data) )) );
+   attr_time = EXTRACT_32BITS(data);
+   strcpy(string, ctime(&attr_time));
+   /* Get rid of the newline */
+   string[24] = '\0';
+   printf("{%.24s}", string);
    return;
    
    trunc:
@@ -636,43 +661,66 @@ static void print_attr_time(register u_char *data, u_int length, u_short attr_co
 /***********************************/
 static void print_attr_strange(register u_char *data, u_int length, u_short attr_code)
 {
-   u_short len_data = 8;
+   u_short len_data;
    
    switch(attr_code)
    {
       case ARAP_PASS:
+           if (length != 16)
+           {
+               printf("{length %u != 16}", length);
+               return;
+           }
            printf("{User_challenge[");
            TCHECK2(data[0],8);
+           len_data = 8;
            PRINT_HEX(len_data, data);
            printf("] User_resp[");
            TCHECK2(data[0],8);
+           len_data = 8;
            PRINT_HEX(len_data, data);
            printf("]}");
         break;
         
       case ARAP_FEATURES:
+           if (length != 14)
+           {
+               printf("{length %u != 14}", length);
+               return;
+           }
+           TCHECK2(data[0],1);
            if (*data)
               printf("{User_can_change_pass");
            else
               printf("{User_cant_change_pass");
-           TCHECK2(data[0],1);
            data++;
+           TCHECK2(data[0],1);
            printf(" Min_pass_len[%d]",*data);
+           data++;
            printf(" Pass_created_at[");
-           TCHECK2(data[0],8);
+           TCHECK2(data[0],4);
+           len_data = 4;
            PRINT_HEX(len_data, data);
            printf("] Pass_expired_in[");
-           TCHECK2(data[0],8);
+           TCHECK2(data[0],4);
+           len_data = 4;
            PRINT_HEX(len_data, data);
            printf("] Current_time[");
-           TCHECK2(data[0],8);
+           len_data = 4;
+           TCHECK2(data[0],4);
            PRINT_HEX(len_data, data);
            printf("]}");
         break;
 
       case ARAP_CHALLENGE_RESP:
+           if (length < 8)
+           {
+               printf("{length %u != 8}", length);
+               return;
+           }
            printf("{");
            TCHECK2(data[0],8);
+           len_data = 8;
            PRINT_HEX(len_data, data);
            printf("}");
         break;
@@ -685,7 +733,7 @@ static void print_attr_strange(register u_char *data, u_int length, u_short attr
 
 
 static void
-radius_attr_print(register u_char *attr, u_int length)
+radius_attr_print(register const u_char *attr, u_int length)
 {
    register const struct radius_attr *rad_attr = (struct radius_attr *)attr;
    
@@ -698,6 +746,11 @@ radius_attr_print(register u_char *attr, u_int length)
    printf(" Attr[ ");
    while (length > 0)
    {
+     if (rad_attr->len == 0)
+     {
+       printf("(zero-length attribute)");
+       return;
+     }
      if ( rad_attr->len <= length )
      {
         if ( !rad_attr->type || (rad_attr->type > (TAM_SIZE(attr_type)-1))  )
@@ -706,9 +759,13 @@ radius_attr_print(register u_char *attr, u_int length)
         {
            printf(" %s",attr_type[rad_attr->type].name);
 
-           if ( attr_type[rad_attr->type].print_func )
-              (*attr_type[rad_attr->type].print_func)( ((char *)(rad_attr+1)),
+           if (rad_attr->len > 2)
+           {
+               if ( attr_type[rad_attr->type].print_func )
+                  (*attr_type[rad_attr->type].print_func)( 
+                                          ((u_char *)(rad_attr+1)),
                                            rad_attr->len - 2, rad_attr->type);
+           }
         }
      }
      else
@@ -729,17 +786,30 @@ radius_print(const u_char *dat, u_int length)
 {
    register const struct radius_hdr *rad;
    register int i;
+   int len;
    
-   i = min(length, snapend - dat) - sizeof(*rad);
+   i = min(length, snapend - dat);
 
-   if (i < 0) 
+   if (i < MIN_RADIUS_LEN)
    {
          printf(" [|radius]");
          return;
    }
 
    rad = (struct radius_hdr *)dat;
+   len = ntohs(rad->len);
+
+   if (len < MIN_RADIUS_LEN)
+   {
+         printf(" [|radius]");
+         return;
+   }
+
+   if (len < i)
+         i = len;
+   
+   i -= MIN_RADIUS_LEN;
+
    switch (rad->code) 
    {
      case RADCMD_ACCESS_REQ:
@@ -785,5 +855,5 @@ radius_print(const u_char *dat, u_int length)
    printf(" [id %d]", rad->id);
  
    if (i)
-      radius_attr_print( ((char *)(rad+1)), i);  
+      radius_attr_print( dat + MIN_RADIUS_LEN, i);  
 }