[0001]
[0002]
[0003]
[0004]
[0005]
[0006]
[0007]
[0008]
[0009]
[0010]
[0011]
[0012]
[0013]
[0014]
[0015]
[0016]
[0017]
[0018]
[0019]
[0020]
[0021]
[0022]
[0023]
[0024]
[0025]
[0026]
[0027]
[0028]
[0029]
[0030]
[0031]
[0032]
[0033]
[0034]
[0035]
[0036]
[0037]
[0038]
[0039]
[0040]
[0041]
[0042]
[0043]
[0044]
[0045]
[0046]
[0047]
[0048]
[0049]
[0050]
[0051]
[0052]
[0053]
[0054]
[0055]
[0056]
[0057]
[0058]
[0059]
[0060]
[0061]
[0062]
[0063]
[0064]
[0065]
[0066]
[0067]
[0068]
[0069]
[0070]
[0071]
[0072]
[0073]
[0074]
[0075]
[0076]
[0077]
[0078]
[0079]
[0080]
[0081]
[0082]
[0083]
[0084]
[0085]
[0086]
[0087]
[0088]
[0089]
[0090]
[0091]
[0092]
[0093]
[0094]
[0095]
[0096]
[0097]
[0098]
[0099]
[0100]
[0101]
[0102]
[0103]
[0104]
[0105]
[0106]
[0107]
[0108]
[0109]
[0110]
[0111]
[0112]
[0113]
[0114]
[0115]
[0116]
[0117]
[0118]
[0119]
[0120]
[0121]
[0122]
[0123]
[0124]
[0125]
[0126]
[0127]
[0128]
[0129]
[0130]
[0131]
[0132]
[0133]
[0134]
[0135]
[0136]
[0137]
[0138]
[0139]
[0140]
[0141]
[0142]
[0143]
[0144]
[0145]
[0146]
[0147]
[0148]
[0149]
[0150]
[0151]
[0152]
[0153]
[0154]
[0155]
[0156]
[0157]
[0158]
[0159]
[0160]
[0161]
[0162]
[0163]
[0164]
[0165]
[0166]
[0167]
[0168]
[0169]
[0170]
[0171]
[0172]
[0173]
[0174]
[0175]
[0176]
[0177]
[0178]
[0179]
[0180]
[0181]
[0182]
[0183]
[0184]
[0185]
[0186]
[0187]
[0188]
[0189]
[0190]
[0191]
[0192]
[0193]
[0194]
[0195]
[0196]
[0197]
[0198]
[0199]
[0200]
[0201]
[0202]
[0203]
[0204]
[0205]
[0206]
[0207]
[0208]
[0209]
[0210]
[0211]
[0212]
[0213]
[0214]
[0215]
[0216]
[0217]
[0218]
[0219]
[0220]
[0221]
[0222]
[0223]
[0224]
[0225]
[0226]
[0227]
[0228]
[0229]
[0230]
[0231]
[0232]
[0233]
[0234]
[0235]
[0236]
[0237]
[0238]
[0239]
[0240]
[0241]
[0242]
[0243]
[0244]
[0245]
[0246]
[0247]
[0248]
[0249]
[0250]
[0251]
[0252]
[0253]
[0254]
[0255]
[0256]
[0257]
[0258]
[0259]
[0260]
[0261]
[0262]
[0263]
[0264]
[0265]
[0266]
[0267]
[0268]
[0269]
[0270]
[0271]
[0272]
[0273]
[0274]
[0275]
[0276]
[0277]
[0278]
[0279]
[0280]
[0281]
[0282]
[0283]
[0284]
[0285]
[0286]
[0287]
[0288]
[0289]
[0290]
[0291]
[0292]
[0293]
[0294]
[0295]
[0296]
[0297]
[0298]
[0299]
[0300]
[0301]
[0302]
[0303]
[0304]
[0305]
[0306]
[0307]
[0308]
[0309]
[0310]
[0311]
[0312]
[0313]
[0314]
[0315]
[0316]
[0317]
[0318]
[0319]
[0320]
[0321]
[0322]
[0323]
[0324]
[0325]
[0326]
[0327]
[0328]
[0329]
[0330]
[0331]
[0332]
[0333]
[0334]
[0335]
[0336]
[0337]
[0338]
[0339]
[0340]
[0341]
[0342]
[0343]
[0344]
[0345]
[0346]
[0347]
[0348]
[0349]
[0350]
[0351]
[0352]
[0353]
[0354]
[0355]
[0356]
[0357]
[0358]
[0359]
[0360]
[0361]
[0362]
[0363]
[0364]
[0365]
[0366]
[0367]
[0368]
[0369]
[0370]
[0371]
[0372]
[0373]
[0374]
[0375]
[0376]
[0377]
[0378]
[0379]
[0380]
[0381]
[0382]
[0383]
[0384]
[0385]
[0386]
[0387]
[0388]
[0389]
[0390]
[0391]
[0392]
[0393]
[0394]
[0395]
[0396]
[0397]
[0398]
[0399]
[0400]
[0401]
[0402]
[0403]
[0404]
[0405]
[0406]
[0407]
[0408]
[0409]
[0410]
[0411]
[0412]
[0413]
[0414]
[0415]
[0416]
[0417]
[0418]
[0419]
[0420]
[0421]
[0422]
[0423]
[0424]
[0425]
[0426]
[0427]
[0428]
[0429]
[0430]
[0431]
[0432]
[0433]
[0434]
[0435]
[0436]
[0437]
[0438]
[0439]
[0440]
[0441]
[0442]
[0443]
[0444]
[0445]
[0446]
[0447]
[0448]
[0449]
[0450]
[0451]
[0452]
[0453]
[0454]
[0455]
[0456]
[0457]
[0458]
[0459]
[0460]
[0461]
[0462]
[0463]
[0464]
[0465]
[0466]
[0467]
[0468]
[0469]
[0470]
[0471]
[0472]
[0473]
[0474]
[0475]
[0476]
[0477]
[0478]
[0479]
[0480]
[0481]
[0482]
[0483]
[0484]
[0485]
[0486]
[0487]
[0488]
[0489]
[0490]
[0491]
[0492]
[0493]
[0494]
[0495]
[0496]
[0497]
[0498]
[0499]
[0500]
[0501]
[0502]
[0503]
[0504]
[0505]
[0506]
[0507]
[0508]
[0509]
[0510]
[0511]
[0512]
[0513]
[0514]
[0515]
[0516]
[0517]
[0518]
[0519]
[0520]
[0521]
[0522]
[0523]
[0524]
[0525]
[0526]
[0527]
[0528]
[0529]
[0530]
[0531]
[0532]
[0533]
/*****************************************************************************/
/*
                                HTTP2watch.c


VERSION HISTORY
---------------
14-FEB-2019  MGD  Http2WatchFrame() relax WATCH from module to regular
17-AUG-2015  MGD  initial
*/
/*****************************************************************************/

#ifdef WASD_VMS_V7
#  undef __VMS_VER
#  define __VMS_VER 70000000
#  undef __CRTL_VER
#  define __CRTL_VER 70000000
#else
#  ifdef WASD_VMS_V7
#     undef _VMS__V6__SOURCE
#     define _VMS__V6__SOURCE
#     undef __VMS_VER
#     define __VMS_VER 70000000
#     undef __CRTL_VER
#     define __CRTL_VER 70000000
#   endif
#endif

#include <stdio.h>
#include <ctype.h>

#include "wasd.h"

#define WASD_MODULE "HTTP2WATCH"

/******************/
/* global storage */
/******************/

/********************/
/* external storage */
/********************/

extern char  *Http2ErrorArray [];
extern WATCH_STRUCT  Watch;

/*****************************************************************************/
/*
*/

void Http2WatchFrame
(
HTTP2_STRUCT *h2ptr,
uchar *FramePtr,
uchar *DataPtr,
uint BufferLength,
BOOL magic
)
{
   uint  flags, flen, ident, type;
   uchar  *csptr, *fptr, *tptr;
   char  flstr [64];

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (h2ptr, WATCH_MOD_HTTP2))
      WatchThis (WATCHITM(h2ptr), WATCH_MOD_HTTP2, "Http2WatchFrame()");

   fptr = FramePtr;
   HTTP2_GET_24 (fptr, flen);
   HTTP2_GET_8 (fptr, type);
   HTTP2_GET_8 (fptr, flags);
   HTTP2_GET_32 (fptr, ident);

   flstr[0] = '\0';

   switch (type)
   {
      case HTTP2_FRAME_DATA :
           if (magic)
              tptr = "DATA (magic)";
           else
              tptr = "DATA";
           if (flags & HTTP2_FLAG_DATA_END_STR)
              strcat (flstr, " END-STREAM");
           if (flags & HTTP2_FLAG_DATA_PADDED)
              strcat (flstr, " PADDED");
           if (flags & ~(HTTP2_FLAG_DATA_END_STR |
                         HTTP2_FLAG_DATA_PADDED))
              strcat (flstr, " ?");
           break;
      case HTTP2_FRAME_HEADERS :
           tptr = "HEADERS";
           if (flags & HTTP2_FLAG_HEAD_END_STR)
              strcat (flstr, " END-STREAM");
           if (flags & HTTP2_FLAG_HEAD_END_HEAD)
              strcat (flstr, " END-HEADERS");
           if (flags & HTTP2_FLAG_HEAD_PADDED)
              strcat (flstr, " PADDED");
           if (flags & HTTP2_FLAG_HEAD_PRIORITY)
              strcat (flstr, " PRIORITY");
           if (flags & ~(HTTP2_FLAG_HEAD_END_STR |
                         HTTP2_FLAG_HEAD_END_HEAD |
                         HTTP2_FLAG_HEAD_PADDED |
                         HTTP2_FLAG_HEAD_PRIORITY))
              strcat (flstr, " ?");
           break;
      case HTTP2_FRAME_PRIORITY :
           tptr = "PRIORITY";
           break;
      case HTTP2_FRAME_RST_STREAM :
           tptr = "RST_STREAM";
           break;
      case HTTP2_FRAME_SETTINGS :
           tptr = "SETTINGS";
           if (flags & HTTP2_FLAG_SETTINGS_ACK)
              strcat (flstr, " ACKNOWLEDGE");
           if (flags & ~HTTP2_FLAG_PING_ACK)
              strcat (flstr, " ?");
           break;
      case HTTP2_FRAME_PUSH_PROMISE :
           tptr = "PUSH_PROMISE";
           if (flags & HTTP2_FLAG_PUSH_END_HEAD)
              strcat (flstr, " END-HEADERS");
           if (flags & HTTP2_FLAG_PUSH_PADDED)
              strcat (flstr, " PADDED");
           if (flags & ~(HTTP2_FLAG_PUSH_END_HEAD |
                         HTTP2_FLAG_PUSH_PADDED))
              strcat (flstr, " ?");
           break;
      case HTTP2_FRAME_PING :
           tptr = "PING";
           if (flags & HTTP2_FLAG_PING_ACK)
              strcat (flstr, " ACKNOWLEDGE");
           if (flags & ~HTTP2_FLAG_PING_ACK)
              strcat (flstr, " ?");
           break;
      case HTTP2_FRAME_GOAWAY :
           tptr = "GOAWAY";
           break;
      case HTTP2_FRAME_WINDOW_UPDATE :
           tptr = "WINDOW_UPDATE";
           break;
      case HTTP2_FRAME_CONTINUATION :
           tptr = "CONTINUATION";
           if (flags & HTTP2_FLAG_HEAD_END_HEAD)
              strcat (flstr, " END-HEADERS");
           if (flags & ~HTTP2_FLAG_HEAD_END_HEAD)
              strcat (flstr, " ?");
           break;
      default :
           tptr = "?";
   }

   if (flags && !flstr[0]) strcpy (flstr, " ?");

   if (FramePtr >= h2ptr->ReadBufferPtr &&
       FramePtr < h2ptr->ReadBufferPtr + h2ptr->ReadBufferSize)
      csptr = "client";
   else
      csptr = "server";

   WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
"FRAME !AZ length:!UL type:!UL !AZ flags:0x!2XL!AZ ident:!UL",
                 csptr, flen, type, tptr, flags, flstr, ident);

   switch (type)
   {
      case HTTP2_FRAME_DATA :
           if (DataPtr) fptr = DataPtr;
           if (WATCHMOD (h2ptr, WATCH_MOD_HTTP2))
              Http2WatchData (h2ptr, ident, flags, fptr, flen, BufferLength);
           break;
      case HTTP2_FRAME_HEADERS :
      case HTTP2_FRAME_CONTINUATION :
           Http2WatchHeaders (h2ptr, ident, flags, fptr, flen, BufferLength);
           break;
      case HTTP2_FRAME_PRIORITY :
           Http2WatchPriority (h2ptr, ident, fptr, flen);
           break;
      case HTTP2_FRAME_RST_STREAM :
           Http2WatchRstStream (h2ptr, ident, fptr, flen);
           break;
      case HTTP2_FRAME_SETTINGS :
           Http2WatchSettings (h2ptr, csptr, fptr, flen);
           break;
      case HTTP2_FRAME_PUSH_PROMISE :
           Http2WatchPushPromise (h2ptr, ident, flags, fptr, flen);
           break;
      case HTTP2_FRAME_PING :
           Http2WatchPing (h2ptr, fptr, flen);
           break;
      case HTTP2_FRAME_GOAWAY :
           Http2WatchGoAway (h2ptr, fptr, flen);
           break;
      case HTTP2_FRAME_WINDOW_UPDATE :
           Http2WatchWindowUpdate (h2ptr, ident, fptr, flen);
           break;
      default :
           WatchThis (WATCHITM(h2ptr), WATCH_HTTP2, "FRAME error!");
   }
}

/*****************************************************************************/
/*
*/

void Http2WatchData
(
HTTP2_STRUCT *h2ptr,
uint ident,
uint flags,
uchar *fptr,
uint flen,
uint blen
)
{
   uint  padlen;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (h2ptr, WATCH_MOD_HTTP2))
   {
      if (flags & HTTP2_FLAG_DATA_PADDED)
         HTTP2_GET_8 (fptr, padlen)
      else
         padlen = 0;

      WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
                 "DATA padding:!UL length:!UL", padlen, flen - padlen);

      /* dump only as many bytes as we have */
///      WatchDataDump (fptr, blen >= flen - padlen ? flen - padlen : blen);
   }
}

/*****************************************************************************/
/*
*/

void Http2WatchGoAway
(
HTTP2_STRUCT *h2ptr,
uchar *fptr,
uint flen
)
{
   uint  addlen, lastid, error;

   /*********/
   /* begin */
   /*********/

   HTTP2_GET_32 (fptr, lastid);
   lastid &= 0x7fffffff;
   HTTP2_GET_32 (fptr, error);

   addlen = flen - sizeof(uint) - sizeof(uint);

   WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
              "GOAWAY lastident:!UL error:!UL \"!AZ\"!AZ!#AZ!AZ",
              lastid, error, Http2ErrorString(error),
              addlen ? " \"" : "", addlen, fptr,
              addlen ? "\"" : "");
}

/*****************************************************************************/
/*
*/

void Http2WatchHeaders
(
HTTP2_STRUCT *h2ptr,
uint ident,
uint flags,
uchar *fptr,
uint flen,
uint blen
)
{
   uint  hbflen,
         padlen,
         depend,
         weight;
   uchar  *bptr;

   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (h2ptr, WATCH_MOD_HTTP2))
   {
      bptr = fptr;
      if (flags & HTTP2_FLAG_HEAD_PADDED)
         HTTP2_GET_8 (fptr, padlen)
      else
         padlen = 0;
      if (flags & HTTP2_FLAG_HEAD_PRIORITY)
      {
         HTTP2_GET_32 (fptr, depend)
         HTTP2_GET_8 (fptr, weight)
      }
      else
         depend = weight = 0;

      WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
"HEADERS str:!&B end:!&B pad:!&B prio:!&B \
padding:!UL depend:!UL (ex:!&B) header:!UL (!UL)",
                 flags & HTTP2_FLAG_HEAD_END_STR,
                 flags & HTTP2_FLAG_HEAD_END_HEAD,
                 flags & HTTP2_FLAG_HEAD_PADDED,
                 flags & HTTP2_FLAG_HEAD_PRIORITY,
                 padlen, depend, depend & 0x80000000, flen - padlen, blen);

      /* dump only as many bytes as we have */
      WatchDataDump (fptr, blen >= flen - padlen ? flen - padlen : blen);
   }
}

/*****************************************************************************/
/*
*/

void Http2WatchPing
(
HTTP2_STRUCT *h2ptr,
uchar *fptr,
uint flen
)
{
   /*********/
   /* begin */
   /*********/

   if (WATCHMOD (h2ptr, WATCH_MOD_HTTP2))
      WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
                 "PING !2XL!2XL!2XL!2XL!2XL!2XL!2XL!2XL",
                 fptr[0],fptr[1],fptr[2],fptr[3],
                 fptr[4],fptr[5],fptr[6],fptr[7]);
}

/*****************************************************************************/
/*
*/

void Http2WatchPriority
(
HTTP2_STRUCT *h2ptr,
uint ident,
uchar *fptr,
uint flen
)
{
   uint  depend, weight;

   /*********/
   /* begin */
   /*********/

   HTTP2_GET_32 (fptr, depend)
   HTTP2_GET_8 (fptr, weight)

   WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
              "PRIORITY depend:!UL (ex:!UL) weight:!UL",
              depend & 0x7fffffff, depend & 0x80000000, weight+1);
}

/*****************************************************************************/
/*
*/

void Http2WatchPushPromise
(
HTTP2_STRUCT *h2ptr,
uint ident,
uint flags,
uchar *fptr,
uint flen
)
{
   uint  hbflen, padlen, promid;

   /*********/
   /* begin */
   /*********/

   if (flags & HTTP2_FLAG_DATA_PADDED)
      HTTP2_GET_8 (fptr, padlen)
   else
      padlen = 0;

   HTTP2_GET_32 (fptr, promid);
   promid &= 0x7fffffff;

   hbflen = flen - sizeof(uchar) - sizeof(uint) - sizeof(uchar) - padlen;

   WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
              "PUSH_PROMISE padding:!UL promid:!UL header:!UL",
              padlen, promid, hbflen);

   if (WATCHMOD (h2ptr, WATCH_MOD_HTTP2))
      WatchData (fptr, hbflen);
}

/*****************************************************************************/
/*
*/

void Http2WatchRstStream
(
HTTP2_STRUCT *h2ptr,
uint ident,
uchar *fptr,
uint flen
)
{
   uint  error;

   /*********/
   /* begin */
   /*********/

   HTTP2_GET_32 (fptr, error);

   WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
              "RST_STREAM ident:!UL error:!UL \"!AZ\"",
              ident, error, Http2ErrorString(error));
}

/*****************************************************************************/
/*
*/

void Http2WatchSettings
(
HTTP2_STRUCT *h2ptr,
uchar *csptr,
uchar *fptr,
uint flen
)
{
   uint  setting, value;
   char  *cptr;

   /*********/
   /* begin */
   /*********/

   for (;(int)flen >= 6; flen -= 6)
   {
      HTTP2_GET_16 (fptr, setting);
      HTTP2_GET_32 (fptr, value);

      switch (setting)
      {
         case HTTP2_SETTING_MAX_HEAD_TABLE_SIZE :
              cptr = "header table size"; break;
         case HTTP2_SETTING_ENABLE_PUSH :
              cptr = "server push enabled"; break;
         case HTTP2_SETTING_MAX_CONC_STREAMS :
              cptr = "max concurrent streams"; break;
         case HTTP2_SETTING_INIT_WIN_SIZE :
              cptr = "initial window size"; break;
         case HTTP2_SETTING_MAX_FRAME_SIZE :
              cptr = "max frame size"; break;
         case HTTP2_SETTING_MAX_HEAD_LIST_SIZE :
              cptr = "max header list size"; break;
         default : cptr = "(unknown)";
      }

      WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
                 "SETTING !AZ !AZ: !UL", csptr, cptr, value);
   }

   if (flen) WatchThis (WATCHITM(h2ptr), WATCH_HTTP2, "SETTING error!!");
}

/*****************************************************************************/
/*
*/

void Http2WatchWindowUpdate
(
HTTP2_STRUCT *h2ptr,
uint ident,
uchar *fptr,
uint flen
)
{
   uint  value;

   /*********/
   /* begin */
   /*********/

   HTTP2_GET_32 (fptr, value);
   value &= 0x7fffffff;

   WatchThis (WATCHITM(h2ptr), WATCH_HTTP2,
              "WINDOW_UPDATE ident:!UL value:!UL", ident, value);
}

/*****************************************************************************/
/*
*/

void Http2WatchError
(
HTTP2_STRUCT *h2ptr,
uint error
)
{
   char  *sptr;

   /*********/
   /* begin */
   /*********/

   if (error < HTTP2_ERROR_COUNT)
      sptr = Http2ErrorArray[error];
   else
      sptr = "?";

   WatchThis (WATCHITM(h2ptr), WATCH_HTTP2, "ERROR !UL !AZ", error, sptr);

}

/*****************************************************************************/