YAZ  5.23.1
dumpber.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14 
15 #include <stdio.h>
16 #include "odr-priv.h"
17 
18 static int do_dumpBER(FILE *f, const char *buf, int len, int level, int offset)
19 {
20  int res, ll, zclass, tag, cons, lenlen, taglen;
21  const char *b = buf;
22  char level_str[80];
23 
24  if (level >= 15)
25  sprintf(level_str, "level=%-6d%*s", level, 18, "");
26  else
27  sprintf(level_str, "%*s", level * 2, "");
28 
29  if (!len)
30  return 0;
31  if (!buf[0] && !buf[1])
32  return 0;
33  if ((res = ber_dectag(b, &zclass, &tag, &cons, len)) <= 0)
34  return 0;
35  if (res > len)
36  {
37  fprintf(f, "%5d: %s : Unexpected end of buffer\n", offset, level_str);
38  return 0;
39  }
40  fprintf(f, "%5d: %s", offset, level_str);
41  if (zclass == ODR_UNIVERSAL)
42  {
43  static char *nl[] =
44  {
45  "[Univ 0]", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
46  "NULL", "OID", "OBJECT DESCIPTOR", "EXTERNAL", "REAL",
47  "ENUM", "[UNIV 11]", "[UNIV 12]", "[UNIV 13]", "[UNIV 14]",
48  "[UNIV 15]", "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING",
49  "[UNIV 20]", "[UNIV 21]", "[UNIV 22]", "[UNIV 23]", "[UNIV 24]",
50  "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "[UNIV 28]"
51  };
52 
53  if (tag >= 0 && tag < 28)
54  fprintf(f, "%s", nl[tag]);
55  else
56  fprintf(f, "[UNIV %d]", tag);
57  }
58  else if (zclass == ODR_CONTEXT)
59  fprintf(f, "[%d]", tag);
60  else
61  fprintf(f, "[%d:%d]", zclass, tag);
62  b += res;
63  taglen = res;
64  len -= res;
65  if ((res = ber_declen(b, &ll, len)) <= 0)
66  {
67  fprintf(f, "\n%sBad length\n", level_str);
68  return 0;
69  }
70  lenlen = res;
71  b += res;
72  len -= res;
73  if (ll >= 0)
74  fprintf(f, " len=%d", ll);
75  else
76  fprintf(f, " len=?");
77  fprintf(f, " tl=%d, ll=%d cons=%d\n", taglen, lenlen, cons);
78  if (!cons)
79  {
80  if (ll < 0 || ll > len)
81  {
82  fprintf(f, "%sBad length on primitive type. ll=%d len=%d\n",
83  level_str, ll, len);
84  return 0;
85  }
86  return ll + (b - buf);
87  }
88  if (ll >= 0)
89  {
90  if (ll > len)
91  {
92  fprintf(f, "%sBad length of constructed type ll=%d len=%d\n",
93  level_str, ll, len);
94  return 0;
95  }
96  len = ll;
97  }
98  /* constructed - cycle through children */
99  while ((ll == -1 && len >= 2) || (ll >= 0 && len))
100  {
101  if (ll == -1 && *b == 0 && *(b + 1) == 0)
102  break;
103  if (!(res = do_dumpBER(f, b, len, level + 1, offset + (b - buf))))
104  {
105  fprintf(f, "%s Dump of content element failed\n", level_str);
106  return 0;
107  }
108  b += res;
109  len -= res;
110  if (len < 0)
111  {
112  fprintf(f, "%sBad length\n", level_str);
113  return 0;
114  }
115  }
116  if (ll == -1)
117  {
118  if (len < 2)
119  {
120  fprintf(f, "%sBuffer too short in indefinite length\n",
121  level_str);
122  return 0;
123  }
124  return (b - buf) + 2;
125  }
126  return b - buf;
127 }
128 
129 int odr_dumpBER(FILE *f, const char *buf, int len)
130 {
131  return do_dumpBER(f, buf, len, 0, 0);
132 }
133 /*
134  * Local variables:
135  * c-basic-offset: 4
136  * c-file-style: "Stroustrup"
137  * indent-tabs-mode: nil
138  * End:
139  * vim: shiftwidth=4 tabstop=8 expandtab
140  */
141 
int ber_declen(const char *buf, int *len, int max)
Definition: ber_len.c:93
#define ODR_UNIVERSAL
Definition: odr.h:65
Internal ODR definitions.
static int do_dumpBER(FILE *f, const char *buf, int len, int level, int offset)
Definition: dumpber.c:18
int odr_dumpBER(FILE *f, const char *buf, int len)
Definition: dumpber.c:129
int ber_dectag(const char *cp, int *zclass, int *tag, int *constructed, int max)
Decodes BER identifier octets.
Definition: ber_tag.c:165
#define ODR_CONTEXT
Definition: odr.h:67