Print this page
    
dccp: snoop, build system fixes
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipsec.c
          +++ new/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipsec.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  
  26   26  #include <stdio.h>
  27   27  #include <stdlib.h>
  28   28  #include <ctype.h>
  29   29  #include <string.h>
  30   30  #include <fcntl.h>
  31   31  #include <string.h>
  32   32  #include <strings.h>
  33   33  #include <sys/types.h>
  34   34  #include <sys/sysmacros.h>
  35   35  #include <sys/time.h>
  36   36  
  37   37  #include <sys/socket.h>
  38   38  #include <sys/sockio.h>
  39   39  #include <net/if.h>
  40   40  #include <netinet/in_systm.h>
  41   41  #include <netinet/in.h>
  42   42  #include <netinet/ip.h>
  43   43  #include <netinet/ip_icmp.h>
  44   44  #include <netinet/icmp6.h>
  45   45  #include <netinet/if_ether.h>
  46   46  #include <inet/ipsecesp.h>
  47   47  #include <inet/ipsecah.h>
  48   48  #include "snoop.h"
  49   49  
  50   50  /* ARGSUSED */
  51   51  int
  52   52  interpret_esp(int flags, uint8_t *hdr, int iplen, int fraglen)
  53   53  {
  54   54          /* LINTED: alignment */
  55   55          esph_t *esph = (esph_t *)hdr;
  56   56          esph_t *aligned_esph;
  57   57          esph_t storage; /* In case hdr isn't aligned. */
  58   58          char *line;
  59   59  
  60   60          if (fraglen < sizeof (esph_t))
  61   61                  return (fraglen);       /* incomplete header */
  62   62  
  63   63          if (!IS_P2ALIGNED(hdr, 4)) {
  64   64                  aligned_esph = &storage;
  65   65                  bcopy(hdr, aligned_esph, sizeof (esph_t));
  66   66          } else {
  67   67                  aligned_esph = esph;
  68   68          }
  69   69  
  70   70          if (flags & F_SUM) {
  71   71                  line = (char *)get_sum_line();
  72   72                  /*
  73   73                   * sprintf() is safe because line guarantees us 80 columns,
  74   74                   * and SPI and replay certainly won't exceed that.
  75   75                   */
  76   76                  (void) sprintf(line, "ESP SPI=0x%x Replay=%u",
  77   77                      ntohl(aligned_esph->esph_spi),
  78   78                      ntohl(aligned_esph->esph_replay));
  79   79                  line += strlen(line);
  80   80          }
  81   81  
  82   82          if (flags & F_DTAIL) {
  83   83                  show_header("ESP:  ", "Encapsulating Security Payload",
  84   84                      sizeof (esph_t));
  85   85                  show_space();
  86   86                  /*
  87   87                   * sprintf() is safe because get_line guarantees us 80 columns,
  88   88                   * and SPI and replay certainly won't exceed that.
  89   89                   */
  90   90                  (void) sprintf(get_line((char *)&esph->esph_spi - dlc_header,
  91   91                      4), "SPI = 0x%x", ntohl(aligned_esph->esph_spi));
  92   92                  (void) sprintf(get_line((char *)&esph->esph_replay -
  93   93                      dlc_header, 4), "Replay = %u",
  94   94                      ntohl(aligned_esph->esph_replay));
  95   95                  (void) sprintf(get_line((char *)(esph + 1) - dlc_header,
  96   96                      4), "   ....ENCRYPTED DATA....");
  97   97          }
  98   98  
  99   99          return (sizeof (esph_t));
 100  100  }
 101  101  
 102  102  int
 103  103  interpret_ah(int flags, uint8_t *hdr, int iplen, int fraglen)
 104  104  {
 105  105          /* LINTED: alignment */
 106  106          ah_t *ah = (ah_t *)hdr;
 107  107          ah_t *aligned_ah;
 108  108          ah_t storage;   /* In case hdr isn't aligned. */
 109  109          char *line, *buff;
 110  110          uint_t ahlen, auth_data_len;
 111  111          uint8_t *auth_data, *data;
 112  112          int new_iplen;
 113  113          uint8_t proto;
 114  114  
 115  115          if (fraglen < sizeof (ah_t))
 116  116                  return (fraglen);               /* incomplete header */
 117  117  
 118  118          if (!IS_P2ALIGNED(hdr, 4)) {
 119  119                  aligned_ah = (ah_t *)&storage;
 120  120                  bcopy(hdr, &storage, sizeof (ah_t));
 121  121          } else {
 122  122                  aligned_ah = ah;
 123  123          }
 124  124  
 125  125          /*
 126  126           * "+ 8" is for the "constant" part that's not included in the AH
 127  127           * length.
 128  128           *
 129  129           * The AH RFC specifies the length field in "length in 4-byte units,
 130  130           * not counting the first 8 bytes".  So if an AH is 24 bytes long,
 131  131           * the length field will contain "4".  (4 * 4 + 8 == 24).
 132  132           */
 133  133          ahlen = (aligned_ah->ah_length << 2) + 8;
 134  134          fraglen -= ahlen;
 135  135          if (fraglen < 0)
 136  136                  return (fraglen + ahlen);       /* incomplete header */
 137  137  
 138  138          auth_data_len = ahlen - sizeof (ah_t);
 139  139          auth_data = (uint8_t *)(ah + 1);
 140  140          data = auth_data + auth_data_len;
 141  141  
 142  142          if (flags & F_SUM) {
 143  143                  line = (char *)get_sum_line();
 144  144                  (void) sprintf(line, "AH SPI=0x%x Replay=%u",
 145  145                      ntohl(aligned_ah->ah_spi), ntohl(aligned_ah->ah_replay));
 146  146                  line += strlen(line);
 147  147          }
 148  148  
 149  149          if (flags & F_DTAIL) {
 150  150                  show_header("AH:  ", "Authentication Header", ahlen);
 151  151                  show_space();
 152  152                  (void) sprintf(get_line((char *)&ah->ah_nexthdr - dlc_header,
 153  153                      1), "Next header = %d (%s)", aligned_ah->ah_nexthdr,
 154  154                      getproto(aligned_ah->ah_nexthdr));
 155  155                  (void) sprintf(get_line((char *)&ah->ah_length - dlc_header, 1),
 156  156                      "AH length = %d (%d bytes)", aligned_ah->ah_length, ahlen);
 157  157                  (void) sprintf(get_line((char *)&ah->ah_reserved - dlc_header,
 158  158                      2), "<Reserved field = 0x%x>",
 159  159                      ntohs(aligned_ah->ah_reserved));
 160  160                  (void) sprintf(get_line((char *)&ah->ah_spi - dlc_header, 4),
 161  161                      "SPI = 0x%x", ntohl(aligned_ah->ah_spi));
 162  162                  (void) sprintf(get_line((char *)&ah->ah_replay - dlc_header, 4),
 163  163                      "Replay = %u", ntohl(aligned_ah->ah_replay));
 164  164  
 165  165                  /*
 166  166                   * 2 for two hex digits per auth_data byte
 167  167                   * plus one byte for trailing null byte.
 168  168                   */
 169  169                  buff = malloc(auth_data_len * 2 + 1);
 170  170                  if (buff != NULL) {
 171  171                          int i;
 172  172  
 173  173                          for (i = 0; i < auth_data_len; i++)
 174  174                                  sprintf(buff + i * 2, "%02x", auth_data[i]);
 175  175                  }
 176  176  
 177  177                  (void) sprintf(get_line((char *)auth_data - dlc_header,
 178  178                      auth_data_len), "ICV = %s",
 179  179                      (buff == NULL) ? "<out of memory>" : buff);
 180  180  
 181  181                  /* malloc(3c) says I can call free even if buff == NULL */
 182  182                  free(buff);
 183  183  
 184  184                  show_space();
 185  185          }
 186  186  
 187  187          new_iplen = iplen - ahlen;
 188  188          proto = aligned_ah->ah_nexthdr;
 189  189  
 190  190          /*
 191  191           * Print IPv6 Extension Headers, or skip them in the summary case.
 192  192           */
 193  193          if (proto == IPPROTO_HOPOPTS || proto == IPPROTO_DSTOPTS ||
 194  194              proto == IPPROTO_ROUTING || proto == IPPROTO_FRAGMENT) {
 195  195                  (void) print_ipv6_extensions(flags, &data, &proto, &iplen,
 196  196                      &fraglen);
 197  197          }
 198  198  
 199  199          if (fraglen > 0)
 200  200                  switch (proto) {
 201  201                          case IPPROTO_ENCAP:
 202  202                                  /* LINTED: alignment */
 203  203                                  (void) interpret_ip(flags, (struct ip *)data,
 204  204                                      new_iplen);
 205  205                                  break;
 206  206                          case IPPROTO_IPV6:
 207  207                                  (void) interpret_ipv6(flags, (ip6_t *)data,
 208  208                                      new_iplen);
 209  209                                  break;
 210  210                          case IPPROTO_ICMP:
 211  211                                  (void) interpret_icmp(flags,
 212  212                                      /* LINTED: alignment */
 213  213                                      (struct icmp *)data, new_iplen, fraglen);
 214  214                                  break;
 215  215                          case IPPROTO_ICMPV6:
 216  216                                  /* LINTED: alignment */
 217  217                                  (void) interpret_icmpv6(flags, (icmp6_t *)data,
 218  218                                      new_iplen, fraglen);
 219  219                                  break;
 220  220                          case IPPROTO_TCP:
 221  221                                  (void) interpret_tcp(flags,
 222  222                                      (struct tcphdr *)data, new_iplen, fraglen);
 223  223                                  break;
 224  224  
 225  225                          case IPPROTO_ESP:
 226  226                                  (void) interpret_esp(flags, data, new_iplen,
 227  227                                      fraglen);
 228  228                                  break;
  
    | 
      ↓ open down ↓ | 
    228 lines elided | 
    
      ↑ open up ↑ | 
  
 229  229  
 230  230                          case IPPROTO_AH:
 231  231                                  (void) interpret_ah(flags, data, new_iplen,
 232  232                                      fraglen);
 233  233                                  break;
 234  234  
 235  235                          case IPPROTO_UDP:
 236  236                                  (void) interpret_udp(flags,
 237  237                                      (struct udphdr *)data, new_iplen, fraglen);
 238  238                                  break;
      239 +                        case IPPROTO_DCCP:
      240 +                                (void) interpret_dccp(flags,
      241 +                                    (struct dccphdr *)data, new_iplen, fraglen);
      242 +                                break;
 239  243                          /* default case is to not print anything else */
 240  244                  }
 241  245  
 242  246          return (ahlen);
 243  247  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX