Kannel: Open Source WAP and SMS gateway  svn-r5335
wtp_pdu.c File Reference
#include "gwlib/gwlib.h"
#include "wtp_pdu.h"
#include "wtp_pdu.def"

Go to the source code of this file.

Macros

#define PDU(name, docstring, fields, is_valid)
 
#define UINT(field, docstring, bits)   p->field = 0;
 
#define UINTVAR(field, docstring)   p->field = 0;
 
#define OCTSTR(field, docstring, lengthfield)   p->field = NULL;
 
#define REST(field, docstring)   p->field = NULL;
 
#define TYPE(bits, value)
 
#define RESERVED(bits)
 
#define TPI(confield)
 
#define PDU(name, docstring, fields, is_valid)
 
#define UINT(field, docstring, bits)
 
#define UINTVAR(field, docstring)
 
#define OCTSTR(field, docstring, lengthfield)   octstr_destroy(p->field);
 
#define REST(field, docstring)   octstr_destroy(p->field);
 
#define TYPE(bits, value)
 
#define RESERVED(bits)
 
#define TPI(confield)
 
#define PDU(name, docstring, fields, is_valid)
 
#define UINT(field, docstring, bits)   bitpos += (bits);
 
#define UINTVAR(field, docstring)
 
#define OCTSTR(field, docstring, lengthfield)
 
#define REST(field, docstring)
 
#define TYPE(bits, value)
 
#define RESERVED(bits)   bitpos += (bits);
 
#define TPI(confield)
 
#define PDU(name, docstring, fields, is_valid)
 
#define UINT(field, docstring, bits)
 
#define UINTVAR(field, docstring)
 
#define OCTSTR(field, docstring, lengthfield)
 
#define REST(field, docstring)
 
#define TYPE(bits, value)   bitpos += (bits);
 
#define RESERVED(bits)   bitpos += (bits);
 
#define TPI(confield)
 
#define PDU(name, docstring, fields, is_valid)
 
#define UINT(field, docstring, bits)
 
#define UINTVAR(field, docstring)
 
#define OCTSTR(field, docstring, lengthfield)   p->lengthfield = octstr_len(p->field);
 
#define REST(field, docstring)
 
#define TYPE(bits, value)
 
#define RESERVED(bits)
 
#define TPI(confield)   p->confield = pdu->options != NULL && gwlist_len(pdu->options) > 0;
 
#define PDU(name, docstring, fields, is_valid)
 
#define UINT(field, docstring, bits)
 
#define UINTVAR(field, docstring)
 
#define OCTSTR(field, docstring, lengthfield)
 
#define REST(field, docstring)
 
#define TYPE(bits, value)
 
#define RESERVED(bits)   bitpos += (bits);
 
#define TPI(confield)
 
#define PDU(name, docstring, fields, is_valid)
 
#define UINT(field, docstring, bits)   debug(dbg, 0, "%*s %s: %lu", level, "", docstring, p->field);
 
#define UINTVAR(field, docstring)   debug(dbg, 0, "%*s %s: %lu", level, "", docstring, p->field);
 
#define OCTSTR(field, docstring, lengthfield)
 
#define REST(field, docstring)
 
#define TYPE(bits, value)
 
#define RESERVED(bits)
 
#define TPI(confield)   dump_tpis(pdu->options, level);
 

Functions

WTP_PDUwtp_pdu_create (int type)
 
void wtp_pdu_destroy (WTP_PDU *pdu)
 
void wtp_tpi_destroy (WTP_TPI *p)
 
void wtp_pdu_append_tpi (WTP_PDU *pdu, int type, Octstr *data)
 
static long unpack_tpis (Octstr *data, long bitpos, WTP_PDU *pdu)
 
static long pack_tpis (Octstr *data, long bitpos, List *tpis)
 
static void dump_tpis (List *tpis, int level)
 
static int wtp_pdu_type (Octstr *data)
 
WTP_PDUwtp_pdu_unpack (Octstr *data)
 
static void fixup_length_fields (WTP_PDU *pdu)
 
Octstrwtp_pdu_pack (WTP_PDU *pdu)
 
void wtp_pdu_dump (WTP_PDU *pdu, int level)
 

Macro Definition Documentation

◆ OCTSTR [1/7]

#define OCTSTR (   field,
  docstring,
  lengthfield 
)    p->field = NULL;

◆ OCTSTR [2/7]

#define OCTSTR (   field,
  docstring,
  lengthfield 
)    octstr_destroy(p->field);

◆ OCTSTR [3/7]

#define OCTSTR (   field,
  docstring,
  lengthfield 
)

◆ OCTSTR [4/7]

#define OCTSTR (   field,
  docstring,
  lengthfield 
)
Value:
gw_assert(bitpos % 8 == 0); \
p->field = octstr_copy(data, bitpos / 8, p->lengthfield); \
bitpos += 8 * p->lengthfield;
gw_assert(wtls_machine->packet_to_send !=NULL)
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178

◆ OCTSTR [5/7]

#define OCTSTR (   field,
  docstring,
  lengthfield 
)    p->lengthfield = octstr_len(p->field);

◆ OCTSTR [6/7]

#define OCTSTR (   field,
  docstring,
  lengthfield 
)
Value:
gw_assert(bitpos % 8 == 0); \
if (p->field != NULL) \
octstr_append(data, p->field); \
bitpos += 8 * octstr_len(p->field);
gw_assert(wtls_machine->packet_to_send !=NULL)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ OCTSTR [7/7]

#define OCTSTR (   field,
  docstring,
  lengthfield 
)
Value:
debug(dbg, 0, "%*s %s:", level, "", docstring); \
octstr_dump(p->field, level + 1);
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ PDU [1/7]

#define PDU (   name,
  docstring,
  fields,
  is_valid 
)
Value:
case name: {\
struct name *p; p = &pdu->u.name; \
fields \
} break;
char * name
Definition: smsc_cimd2.c:212

◆ PDU [2/7]

#define PDU (   name,
  docstring,
  fields,
  is_valid 
)
Value:
case name: {\
struct name *p; p = &pdu->u.name; \
fields \
} break;
char * name
Definition: smsc_cimd2.c:212

◆ PDU [3/7]

#define PDU (   name,
  docstring,
  fields,
  is_valid 
)
Value:
bitpos = 0; \
thistype = name; \
fields
char * name
Definition: smsc_cimd2.c:212

◆ PDU [4/7]

#define PDU (   name,
  docstring,
  fields,
  is_valid 
)
Value:
case name: { \
struct name *p = &pdu->u.name; \
gw_assert(bitpos % 8 == 0); \
if (bitpos / 8 != octstr_len(data)) { \
warning(0, "Bad length for " #name " PDU, " \
"expected %ld", bitpos / 8); \
} \
if (!(is_valid)) { \
warning(0, #name " PDU failed %s", #is_valid); \
return NULL; \
} \
} break;
gw_assert(wtls_machine->packet_to_send !=NULL)
char * name
Definition: smsc_cimd2.c:212
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ PDU [5/7]

#define PDU (   name,
  docstring,
  fields,
  is_valid 
)
Value:
case name: { \
struct name *p = &pdu->u.name; \
fields \
} break;
char * name
Definition: smsc_cimd2.c:212

◆ PDU [6/7]

#define PDU (   name,
  docstring,
  fields,
  is_valid 
)
Value:
case name: { \
struct name *p = &pdu->u.name; \
gw_assert(bitpos % 8 == 0); \
} break;
gw_assert(wtls_machine->packet_to_send !=NULL)
char * name
Definition: smsc_cimd2.c:212

◆ PDU [7/7]

#define PDU (   name,
  docstring,
  fields,
  is_valid 
)
Value:
case name: { \
struct name *p = &pdu->u.name; \
debug(dbg, 0, "%*sWTP %s PDU at %p:", \
level, "", #name, (void *)pdu); \
fields \
} break;
char * name
Definition: smsc_cimd2.c:212

◆ RESERVED [1/7]

#define RESERVED (   bits)

◆ RESERVED [2/7]

#define RESERVED (   bits)

◆ RESERVED [3/7]

#define RESERVED (   bits)    bitpos += (bits);

◆ RESERVED [4/7]

#define RESERVED (   bits)    bitpos += (bits);

◆ RESERVED [5/7]

#define RESERVED (   bits)

◆ RESERVED [6/7]

#define RESERVED (   bits)    bitpos += (bits);

◆ RESERVED [7/7]

#define RESERVED (   bits)

◆ REST [1/7]

#define REST (   field,
  docstring 
)    p->field = NULL;

◆ REST [2/7]

#define REST (   field,
  docstring 
)    octstr_destroy(p->field);

◆ REST [3/7]

#define REST (   field,
  docstring 
)

◆ REST [4/7]

#define REST (   field,
  docstring 
)
Value:
gw_assert(bitpos % 8 == 0); \
if (bitpos / 8 <= octstr_len(data)) { \
p->field = octstr_copy(data, bitpos / 8, \
octstr_len(data) - bitpos / 8); \
bitpos = octstr_len(data) * 8; \
} else { \
p->field = octstr_create(""); \
}
gw_assert(wtls_machine->packet_to_send !=NULL)
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ REST [5/7]

#define REST (   field,
  docstring 
)

◆ REST [6/7]

#define REST (   field,
  docstring 
)
Value:
gw_assert(bitpos % 8 == 0); \
if (p->field != NULL) \
octstr_append(data, p->field); \
bitpos += 8 * octstr_len(p->field);
gw_assert(wtls_machine->packet_to_send !=NULL)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ REST [7/7]

#define REST (   field,
  docstring 
)
Value:
debug(dbg, 0, "%*s %s:", level, "", docstring); \
octstr_dump(p->field, level + 1);
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ TPI [1/7]

#define TPI (   confield)

◆ TPI [2/7]

#define TPI (   confield)

◆ TPI [3/7]

#define TPI (   confield)

◆ TPI [4/7]

#define TPI (   confield)
Value:
if (p->confield) { \
pdu->options = gwlist_create(); \
bitpos = unpack_tpis(data, bitpos, pdu); \
}
static long unpack_tpis(Octstr *data, long bitpos, WTP_PDU *pdu)
Definition: wtp_pdu.c:164
#define gwlist_create()
Definition: list.h:136

◆ TPI [5/7]

#define TPI (   confield)    p->confield = pdu->options != NULL && gwlist_len(pdu->options) > 0;

◆ TPI [6/7]

#define TPI (   confield)
Value:
if (p->confield) { \
bitpos = pack_tpis(data, bitpos, pdu->options); \
}
static long pack_tpis(Octstr *data, long bitpos, List *tpis)
Definition: wtp_pdu.c:191

◆ TPI [7/7]

#define TPI (   confield)    dump_tpis(pdu->options, level);

◆ TYPE [1/7]

#define TYPE (   bits,
  value 
)

◆ TYPE [2/7]

#define TYPE (   bits,
  value 
)

◆ TYPE [3/7]

#define TYPE (   bits,
  value 
)
Value:
if ((bits) != lastnumbits || bitpos != lastpos) { \
lastval = octstr_get_bits(data, bitpos, (bits)); \
} \
if (lastval == (value)) \
return thistype; \
lastnumbits = (bits); \
lastpos = bitpos;
long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
Definition: octstr.c:1803

◆ TYPE [4/7]

#define TYPE (   bits,
  value 
)    bitpos += (bits);

◆ TYPE [5/7]

#define TYPE (   bits,
  value 
)

◆ TYPE [6/7]

#define TYPE (   bits,
  value 
)
Value:
octstr_set_bits(data, bitpos, (bits), (value)); \
bitpos += (bits);
void octstr_set_bits(Octstr *ostr, long bitpos, int numbits, unsigned long value)
Definition: octstr.c:1849

◆ TYPE [7/7]

#define TYPE (   bits,
  value 
)

◆ UINT [1/7]

#define UINT (   field,
  docstring,
  bits 
)    p->field = 0;

◆ UINT [2/7]

#define UINT (   field,
  docstring,
  bits 
)

◆ UINT [3/7]

#define UINT (   field,
  docstring,
  bits 
)    bitpos += (bits);

◆ UINT [4/7]

#define UINT (   field,
  docstring,
  bits 
)
Value:
p->field = octstr_get_bits(data, bitpos, (bits)); \
bitpos += (bits);
long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
Definition: octstr.c:1803

◆ UINT [5/7]

#define UINT (   field,
  docstring,
  bits 
)

◆ UINT [6/7]

#define UINT (   field,
  docstring,
  bits 
)
Value:
octstr_set_bits(data, bitpos, (bits), p->field); \
bitpos += (bits);
void octstr_set_bits(Octstr *ostr, long bitpos, int numbits, unsigned long value)
Definition: octstr.c:1849

◆ UINT [7/7]

#define UINT (   field,
  docstring,
  bits 
)    debug(dbg, 0, "%*s %s: %lu", level, "", docstring, p->field);

◆ UINTVAR [1/7]

#define UINTVAR (   field,
  docstring 
)    p->field = 0;

◆ UINTVAR [2/7]

#define UINTVAR (   field,
  docstring 
)

◆ UINTVAR [3/7]

#define UINTVAR (   field,
  docstring 
)

◆ UINTVAR [4/7]

#define UINTVAR (   field,
  docstring 
)
Value:
gw_assert(bitpos % 8 == 0); \
p->field = octstr_get_bits(data, bitpos + 1, 7); \
while (octstr_get_bits(data, bitpos, 1)) { \
bitpos += 8; \
p->field <<= 7; \
p->field |= octstr_get_bits(data, bitpos + 1, 7); \
} \
bitpos += 8;
gw_assert(wtls_machine->packet_to_send !=NULL)
long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
Definition: octstr.c:1803

◆ UINTVAR [5/7]

#define UINTVAR (   field,
  docstring 
)

◆ UINTVAR [6/7]

#define UINTVAR (   field,
  docstring 
)
Value:
gw_assert(bitpos % 8 == 0); \
octstr_append_uintvar(data, p->field); \
bitpos = 8 * octstr_len(data);
gw_assert(wtls_machine->packet_to_send !=NULL)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ UINTVAR [7/7]

#define UINTVAR (   field,
  docstring 
)    debug(dbg, 0, "%*s %s: %lu", level, "", docstring, p->field);

Function Documentation

◆ dump_tpis()

static void dump_tpis ( List tpis,
int  level 
)
static

Definition at line 222 of file wtp_pdu.c.

References wtp_tpi::data, debug(), gwlist_get(), gwlist_len(), octstr_dump, and wtp_tpi::type.

222  {
223  int i;
224  int num_tpis;
225  WTP_TPI *tpi;
226 
227  if (tpis == NULL)
228  return;
229 
230  num_tpis = gwlist_len(tpis);
231  for (i = 0; i < num_tpis; i++) {
232  tpi = gwlist_get(tpis, i);
233  debug("wap.wtp", 0, "%*s TPI type %u:", level, "", tpi->type);
234  octstr_dump(tpi->data, level + 1);
235  }
236 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * data
Definition: wtp_pdu.h:72
int type
Definition: wtp_pdu.h:71
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ fixup_length_fields()

static void fixup_length_fields ( WTP_PDU pdu)
static

Definition at line 360 of file wtp_pdu.c.

References wtp_pdu::type.

Referenced by wtp_pdu_pack().

360  {
361  switch (pdu->type) {
362 #define PDU(name, docstring, fields, is_valid) \
363  case name: { \
364  struct name *p = &pdu->u.name; \
365  fields \
366  } break;
367 #define UINT(field, docstring, bits)
368 #define UINTVAR(field, docstring)
369 #define OCTSTR(field, docstring, lengthfield) \
370  p->lengthfield = octstr_len(p->field);
371 #define REST(field, docstring)
372 #define TYPE(bits, value)
373 #define RESERVED(bits)
374 #define TPI(confield) \
375  p->confield = pdu->options != NULL && gwlist_len(pdu->options) > 0;
376 #include "wtp_pdu.def"
377 #undef TPI
378 #undef RESERVED
379 #undef TYPE
380 #undef REST
381 #undef OCTSTR
382 #undef UINTVAR
383 #undef UINT
384 #undef PDU
385  }
386 }
int type
Definition: wtp_pdu.h:84

◆ pack_tpis()

static long pack_tpis ( Octstr data,
long  bitpos,
List tpis 
)
static

Definition at line 191 of file wtp_pdu.c.

References wtp_tpi::data, gw_assert(), gwlist_get(), gwlist_len(), octstr_append(), octstr_len(), octstr_set_bits(), and wtp_tpi::type.

191  {
192  long length;
193  WTP_TPI *tpi;
194  int i;
195  int num_tpis;
196 
197  num_tpis = gwlist_len(tpis);
198  for (i = 0; i < num_tpis; i++) {
199  tpi = gwlist_get(tpis, i);
200  length = octstr_len(tpi->data);
201  octstr_set_bits(data, bitpos, 1, i + 1 < num_tpis);
202  octstr_set_bits(data, bitpos + 1, 4, tpi->type);
203  if (length >= 4) {
204  /* Long TPI */
205  octstr_set_bits(data, bitpos + 5, 1, 1);
206  octstr_set_bits(data, bitpos + 8, 8, length);
207  bitpos += 16;
208  } else {
209  /* Short TPI */
210  octstr_set_bits(data, bitpos + 5, 1, 0);
211  octstr_set_bits(data, bitpos + 6, 2, length);
212  bitpos += 8;
213  }
214  gw_assert(bitpos % 8 == 0);
215  octstr_append(data, tpi->data);
216  bitpos += 8 * length;
217  }
218 
219  return bitpos;
220 }
gw_assert(wtls_machine->packet_to_send !=NULL)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_set_bits(Octstr *ostr, long bitpos, int numbits, unsigned long value)
Definition: octstr.c:1849
Octstr * data
Definition: wtp_pdu.h:72
int type
Definition: wtp_pdu.h:71
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ unpack_tpis()

static long unpack_tpis ( Octstr data,
long  bitpos,
WTP_PDU pdu 
)
static

Definition at line 164 of file wtp_pdu.c.

References gw_assert(), octstr_copy, octstr_get_bits(), type, and wtp_pdu_append_tpi().

164  {
165  long length;
166  int type;
167  Octstr *tpidata;
168  int another;
169 
170  do {
171  another = octstr_get_bits(data, bitpos, 1);
172  type = octstr_get_bits(data, bitpos + 1, 4);
173  if (octstr_get_bits(data, bitpos + 5, 1)) {
174  /* Long TPI */
175  length = octstr_get_bits(data, bitpos + 8, 8);
176  bitpos += 16;
177  } else {
178  /* Short TPI */
179  length = octstr_get_bits(data, bitpos + 6, 2);
180  bitpos += 8;
181  }
182  gw_assert(bitpos % 8 == 0);
183  tpidata = octstr_copy(data, bitpos / 8, length);
184  bitpos += 8 * length;
185  wtp_pdu_append_tpi(pdu, type, tpidata);
186  } while (another);
187 
188  return bitpos;
189 }
void wtp_pdu_append_tpi(WTP_PDU *pdu, int type, Octstr *data)
Definition: wtp_pdu.c:153
gw_assert(wtls_machine->packet_to_send !=NULL)
int type
Definition: smsc_cimd2.c:215
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
Definition: octstr.c:1803
Definition: octstr.c:118

◆ wtp_pdu_append_tpi()

void wtp_pdu_append_tpi ( WTP_PDU pdu,
int  type,
Octstr data 
)

Definition at line 153 of file wtp_pdu.c.

References wtp_tpi::data, gwlist_append(), gwlist_create, wtp_pdu::options, wtp_tpi::type, and type.

Referenced by unpack_tpis(), and wtp_pack_sar_ack().

153  {
154  WTP_TPI *tpi;
155 
156  tpi = gw_malloc(sizeof(*tpi));
157  tpi->type = type;
158  tpi->data = data;
159  if (pdu->options == NULL)
160  pdu->options = gwlist_create();
161  gwlist_append(pdu->options, tpi);
162 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
List * options
Definition: wtp_pdu.h:85
int type
Definition: smsc_cimd2.c:215
Octstr * data
Definition: wtp_pdu.h:72
int type
Definition: wtp_pdu.h:71
#define gwlist_create()
Definition: list.h:136

◆ wtp_pdu_create()

WTP_PDU* wtp_pdu_create ( int  type)

Definition at line 67 of file wtp_pdu.c.

References wtp_pdu::options, wtp_pdu::type, type, and warning().

Referenced by wtp_pack_abort(), wtp_pack_ack(), wtp_pack_invoke(), wtp_pack_result(), wtp_pack_sar_ack(), and wtp_pack_sar_result().

67  {
68  WTP_PDU *pdu;
69 
70  pdu = gw_malloc(sizeof(*pdu));
71  pdu->type = type;
72  pdu->options = NULL;
73 
74  switch (pdu->type) {
75 #define PDU(name, docstring, fields, is_valid) \
76  case name: {\
77  struct name *p; p = &pdu->u.name; \
78  fields \
79  } break;
80 #define UINT(field, docstring, bits) p->field = 0;
81 #define UINTVAR(field, docstring) p->field = 0;
82 #define OCTSTR(field, docstring, lengthfield) p->field = NULL;
83 #define REST(field, docstring) p->field = NULL;
84 #define TYPE(bits, value)
85 #define RESERVED(bits)
86 #define TPI(confield)
87 #include "wtp_pdu.def"
88 #undef TPI
89 #undef RESERVED
90 #undef TYPE
91 #undef REST
92 #undef OCTSTR
93 #undef UINTVAR
94 #undef UINT
95 #undef PDU
96  default:
97  warning(0, "Cannot create unknown WTP PDU type %d", pdu->type);
98  break;
99  }
100 
101  return pdu;
102 }
int type
Definition: wtp_pdu.h:84
List * options
Definition: wtp_pdu.h:85
int type
Definition: smsc_cimd2.c:215
void warning(int err, const char *fmt,...)
Definition: log.c:660

◆ wtp_pdu_destroy()

void wtp_pdu_destroy ( WTP_PDU pdu)

Definition at line 104 of file wtp_pdu.c.

References gwlist_consume(), gwlist_destroy(), gwlist_len(), wtp_pdu::options, wtp_pdu::type, warning(), and wtp_tpi_destroy().

Referenced by main(), unpack_wdp_datagram_real(), wtp_pack_abort(), wtp_pack_ack(), wtp_pack_invoke(), wtp_pack_result(), wtp_pack_sar_ack(), and wtp_pack_sar_result().

104  {
105  if (pdu == NULL)
106  return;
107 
108  switch (pdu->type) {
109 #define PDU(name, docstring, fields, is_valid) \
110  case name: {\
111  struct name *p; p = &pdu->u.name; \
112  fields \
113  } break;
114 #define UINT(field, docstring, bits)
115 #define UINTVAR(field, docstring)
116 #define OCTSTR(field, docstring, lengthfield) octstr_destroy(p->field);
117 #define REST(field, docstring) octstr_destroy(p->field);
118 #define TYPE(bits, value)
119 #define RESERVED(bits)
120 #define TPI(confield)
121 #include "wtp_pdu.def"
122 #undef TPI
123 #undef RESERVED
124 #undef TYPE
125 #undef REST
126 #undef OCTSTR
127 #undef UINTVAR
128 #undef UINT
129 #undef PDU
130  default:
131  warning(0, "Cannot destroy unknown WTP PDU type %d", pdu->type);
132  break;
133  }
134 
135  if (pdu->options) {
136  while (gwlist_len(pdu->options)) {
138  }
139  gwlist_destroy(pdu->options, NULL);
140  }
141 
142  gw_free(pdu);
143 }
int type
Definition: wtp_pdu.h:84
List * options
Definition: wtp_pdu.h:85
void wtp_tpi_destroy(WTP_TPI *p)
Definition: wtp_pdu.c:145
long gwlist_len(List *list)
Definition: list.c:166
void warning(int err, const char *fmt,...)
Definition: log.c:660
void * gwlist_consume(List *list)
Definition: list.c:427
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ wtp_pdu_dump()

void wtp_pdu_dump ( WTP_PDU pdu,
int  level 
)

Definition at line 446 of file wtp_pdu.c.

References debug(), and wtp_pdu::type.

Referenced by main().

446  {
447  char *dbg = "wap.wtp";
448 
449  switch (pdu->type) {
450 #define PDU(name, docstring, fields, is_valid) \
451  case name: { \
452  struct name *p = &pdu->u.name; \
453  debug(dbg, 0, "%*sWTP %s PDU at %p:", \
454  level, "", #name, (void *)pdu); \
455  fields \
456  } break;
457 #define UINT(field, docstring, bits) \
458  debug(dbg, 0, "%*s %s: %lu", level, "", docstring, p->field);
459 #define UINTVAR(field, docstring) \
460  debug(dbg, 0, "%*s %s: %lu", level, "", docstring, p->field);
461 #define OCTSTR(field, docstring, lengthfield) \
462  debug(dbg, 0, "%*s %s:", level, "", docstring); \
463  octstr_dump(p->field, level + 1);
464 #define REST(field, docstring) \
465  debug(dbg, 0, "%*s %s:", level, "", docstring); \
466  octstr_dump(p->field, level + 1);
467 #define TYPE(bits, value)
468 #define RESERVED(bits)
469 #define TPI(confield) dump_tpis(pdu->options, level);
470 #include "wtp_pdu.def"
471 #undef TPI
472 #undef RESERVED
473 #undef TYPE
474 #undef REST
475 #undef OCTSTR
476 #undef UINTVAR
477 #undef UINT
478 #undef PDU
479  default:
480  debug(dbg, 0, "%*sWTP PDU at %p:", level, "", (void *)pdu);
481  debug(dbg, 0, "%*s unknown type %u", level, "", pdu->type);
482  break;
483  }
484 }
int type
Definition: wtp_pdu.h:84
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ wtp_pdu_pack()

Octstr* wtp_pdu_pack ( WTP_PDU pdu)

Definition at line 388 of file wtp_pdu.c.

References fixup_length_fields(), octstr_create, panic, and wtp_pdu::type.

Referenced by main(), wtp_pack_abort(), wtp_pack_ack(), wtp_pack_invoke(), wtp_pack_result(), wtp_pack_sar_ack(), and wtp_pack_sar_result().

388  {
389  Octstr *data;
390  long bitpos;
391 
392  /* We rely on octstr_set_bits to lengthen our octstr as needed. */
393  data = octstr_create("");
394 
395  fixup_length_fields(pdu);
396 
397  bitpos = 0;
398  switch (pdu->type) {
399 #define PDU(name, docstring, fields, is_valid) \
400  case name: { \
401  struct name *p = &pdu->u.name; \
402  fields \
403  gw_assert(bitpos % 8 == 0); \
404  } break;
405 #define UINT(field, docstring, bits) \
406  octstr_set_bits(data, bitpos, (bits), p->field); \
407  bitpos += (bits);
408 #define UINTVAR(field, docstring) \
409  gw_assert(bitpos % 8 == 0); \
410  octstr_append_uintvar(data, p->field); \
411  bitpos = 8 * octstr_len(data);
412 #define OCTSTR(field, docstring, lengthfield) \
413  gw_assert(bitpos % 8 == 0); \
414  if (p->field != NULL) \
415  octstr_append(data, p->field); \
416  bitpos += 8 * octstr_len(p->field);
417 #define REST(field, docstring) \
418  gw_assert(bitpos % 8 == 0); \
419  if (p->field != NULL) \
420  octstr_append(data, p->field); \
421  bitpos += 8 * octstr_len(p->field);
422 #define TYPE(bits, value) \
423  octstr_set_bits(data, bitpos, (bits), (value)); \
424  bitpos += (bits);
425 #define RESERVED(bits) bitpos += (bits);
426 #define TPI(confield) \
427  if (p->confield) { \
428  bitpos = pack_tpis(data, bitpos, pdu->options); \
429  }
430 #include "wtp_pdu.def"
431 #undef TPI
432 #undef RESERVED
433 #undef TYPE
434 #undef REST
435 #undef OCTSTR
436 #undef UINTVAR
437 #undef UINT
438 #undef PDU
439  default:
440  panic(0, "Packing unknown WTP PDU type %ld", (long) pdu->type);
441  }
442 
443  return data;
444 }
int type
Definition: wtp_pdu.h:84
static void fixup_length_fields(WTP_PDU *pdu)
Definition: wtp_pdu.c:360
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
#define panic
Definition: log.h:87

◆ wtp_pdu_type()

static int wtp_pdu_type ( Octstr data)
static

Definition at line 240 of file wtp_pdu.c.

Referenced by wtp_pdu_unpack().

240  {
241  long bitpos;
242  long lastpos = -1;
243  long lastnumbits = -1;
244  long lastval = -1;
245  int thistype;
246 
247  /* This code looks slow, but an optimizing compiler will
248  * reduce it considerably. gcc -O2 will produce a single
249  * call to octstr_get_bits, folllowed by a sequence of
250  * tests on lastval. */
251 
252 /* Only UINT and RESERVED fields may precede the TYPE */
253 #define PDU(name, docstring, fields, is_valid) \
254  bitpos = 0; \
255  thistype = name; \
256  fields
257 #define UINT(field, docstring, bits) bitpos += (bits);
258 #define UINTVAR(field, docstring)
259 #define OCTSTR(field, docstring, lengthfield)
260 #define REST(field, docstring)
261 #define TYPE(bits, value) \
262  if ((bits) != lastnumbits || bitpos != lastpos) { \
263  lastval = octstr_get_bits(data, bitpos, (bits)); \
264  } \
265  if (lastval == (value)) \
266  return thistype; \
267  lastnumbits = (bits); \
268  lastpos = bitpos;
269 #define RESERVED(bits) bitpos += (bits);
270 #define TPI(confield)
271 #include "wtp_pdu.def"
272 #undef TPI
273 #undef RESERVED
274 #undef TYPE
275 #undef REST
276 #undef OCTSTR
277 #undef UINTVAR
278 #undef UINT
279 #undef PDU
280 
281  return -1;
282 }

◆ wtp_pdu_unpack()

WTP_PDU* wtp_pdu_unpack ( Octstr data)

Definition at line 284 of file wtp_pdu.c.

References gw_assert(), wtp_pdu::options, wtp_pdu::type, warning(), and wtp_pdu_type().

Referenced by main(), and unpack_wdp_datagram_real().

284  {
285  WTP_PDU *pdu = NULL;
286  long bitpos = 0;
287 
288  gw_assert(data != NULL);
289 
290  pdu = gw_malloc(sizeof(*pdu));
291 
292  pdu->type = wtp_pdu_type(data);
293  pdu->options = NULL;
294 
295  switch (pdu->type) {
296 #define PDU(name, docstring, fields, is_valid) \
297  case name: { \
298  struct name *p = &pdu->u.name; \
299  fields \
300  gw_assert(bitpos % 8 == 0); \
301  if (bitpos / 8 != octstr_len(data)) { \
302  warning(0, "Bad length for " #name " PDU, " \
303  "expected %ld", bitpos / 8); \
304  } \
305  if (!(is_valid)) { \
306  warning(0, #name " PDU failed %s", #is_valid); \
307  return NULL; \
308  } \
309  } break;
310 #define UINT(field, docstring, bits) \
311  p->field = octstr_get_bits(data, bitpos, (bits)); \
312  bitpos += (bits);
313 #define UINTVAR(field, docstring) \
314  gw_assert(bitpos % 8 == 0); \
315  p->field = octstr_get_bits(data, bitpos + 1, 7); \
316  while (octstr_get_bits(data, bitpos, 1)) { \
317  bitpos += 8; \
318  p->field <<= 7; \
319  p->field |= octstr_get_bits(data, bitpos + 1, 7); \
320  } \
321  bitpos += 8;
322 #define OCTSTR(field, docstring, lengthfield) \
323  gw_assert(bitpos % 8 == 0); \
324  p->field = octstr_copy(data, bitpos / 8, p->lengthfield); \
325  bitpos += 8 * p->lengthfield;
326 #define REST(field, docstring) \
327  gw_assert(bitpos % 8 == 0); \
328  if (bitpos / 8 <= octstr_len(data)) { \
329  p->field = octstr_copy(data, bitpos / 8, \
330  octstr_len(data) - bitpos / 8); \
331  bitpos = octstr_len(data) * 8; \
332  } else { \
333  p->field = octstr_create(""); \
334  }
335 #define TYPE(bits, value) bitpos += (bits);
336 #define RESERVED(bits) bitpos += (bits);
337 #define TPI(confield) \
338  if (p->confield) { \
339  pdu->options = gwlist_create(); \
340  bitpos = unpack_tpis(data, bitpos, pdu); \
341  }
342 #include "wtp_pdu.def"
343 #undef TPI
344 #undef RESERVED
345 #undef TYPE
346 #undef REST
347 #undef OCTSTR
348 #undef UINTVAR
349 #undef UINT
350 #undef PDU
351  default:
352  warning(0, "WTP PDU with unknown type %d", pdu->type);
353  gw_free(pdu);
354  return NULL;
355  }
356 
357  return pdu;
358 }
int type
Definition: wtp_pdu.h:84
gw_assert(wtls_machine->packet_to_send !=NULL)
List * options
Definition: wtp_pdu.h:85
static int wtp_pdu_type(Octstr *data)
Definition: wtp_pdu.c:240
void warning(int err, const char *fmt,...)
Definition: log.c:660

◆ wtp_tpi_destroy()

void wtp_tpi_destroy ( WTP_TPI p)

Definition at line 145 of file wtp_pdu.c.

References wtp_tpi::data, and octstr_destroy().

Referenced by wtp_pdu_destroy().

145  {
146  if (p == NULL)
147  return;
148 
149  octstr_destroy(p->data);
150  gw_free(p);
151 }
Octstr * data
Definition: wtp_pdu.h:72
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.