Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
wtp.c File Reference
#include "wtp.h"
#include "wap_events.h"
#include "wtp_pdu.h"

Go to the source code of this file.

Functions

static WAPEventunpack_wdp_datagram_real (WAPEvent *datagram)
 
static int deduce_tid (Octstr *user_data)
 
static int concatenated_message (Octstr *user_data)
 
static int truncated_datagram (WAPEvent *event)
 
static WAPEventunpack_invoke (WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
 
static WAPEventunpack_segmented_invoke (WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
 
static WAPEventunpack_result (WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
 
static WAPEventunpack_ack (WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
 
static WAPEventunpack_negative_ack (WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
 
static WAPEventunpack_abort (WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
 
static WAPEventpack_error (WAPEvent *datagram)
 
Listwtp_unpack_wdp_datagram (WAPEvent *datagram)
 
int wtp_event_is_for_responder (WAPEvent *event)
 

Function Documentation

static int concatenated_message ( Octstr user_data)
static

Definition at line 434 of file wtp.c.

References octstr_get_char().

Referenced by wtp_unpack_wdp_datagram().

435 {
436  return octstr_get_char(user_data, 0) == 0x00;
437 }
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static int deduce_tid ( Octstr user_data)
static

Definition at line 429 of file wtp.c.

References octstr_get_bits().

Referenced by pack_error().

430 {
431  return octstr_get_bits(user_data, 8, 16);
432 }
long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
Definition: octstr.c:1801
static WAPEvent * pack_error ( WAPEvent datagram)
static

Definition at line 316 of file wtp.c.

References deduce_tid(), gw_assert(), WAPEvent::type, WAPEvent::u, wap_addr_tuple_duplicate(), and wap_event_create.

Referenced by unpack_wdp_datagram_real().

317 {
318  WAPEvent *event;
319 
320  gw_assert(datagram->type == T_DUnitdata_Ind);
321 
322  event = wap_event_create(RcvErrorPDU);
323  event->u.RcvErrorPDU.tid = deduce_tid(datagram->u.T_DUnitdata_Ind.user_data);
324  event->u.RcvErrorPDU.addr_tuple =
325  wap_addr_tuple_duplicate(datagram->u.T_DUnitdata_Ind.addr_tuple);
326 
327  return event;
328 }
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
static int deduce_tid(Octstr *user_data)
Definition: wtp.c:429
#define wap_event_create(type)
Definition: wap_events.h:107
gw_assert(wtls_machine->packet_to_send!=NULL)
WAPEventName type
Definition: wap_events.h:88
union WAPEvent::@87 u
static int truncated_datagram ( WAPEvent event)
static

Definition at line 195 of file wtp.c.

References debug(), gw_assert(), octstr_len(), WAPEvent::type, WAPEvent::u, and wap_event_dump().

Referenced by unpack_wdp_datagram_real().

196 {
197  gw_assert(dgram->type == T_DUnitdata_Ind);
198 
199  if (octstr_len(dgram->u.T_DUnitdata_Ind.user_data) < 3) {
200  debug("wap.wtp", 0, "A too short PDU received");
201  wap_event_dump(dgram);
202  return 1;
203  } else
204  return 0;
205 }
void wap_event_dump(WAPEvent *event)
Definition: wap_events.c:181
gw_assert(wtls_machine->packet_to_send!=NULL)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static WAPEvent * unpack_abort ( WTP_PDU pdu,
WAPAddrTuple addr_tuple 
)
static

Definition at line 303 of file wtp.c.

References wtp_pdu::u, wap_addr_tuple_duplicate(), and wap_event_create.

Referenced by unpack_wdp_datagram_real().

304 {
305  WAPEvent *event;
306 
307  event = wap_event_create(RcvAbort);
308  event->u.RcvAbort.tid = pdu->u.Abort.tid;
309  event->u.RcvAbort.abort_type = pdu->u.Abort.abort_type;
310  event->u.RcvAbort.abort_reason = pdu->u.Abort.abort_reason;
311  event->u.RcvAbort.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);
312 
313  return event;
314 }
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
union wtp_pdu::@107 u
#define wap_event_create(type)
Definition: wap_events.h:107
static WAPEvent * unpack_ack ( WTP_PDU pdu,
WAPAddrTuple addr_tuple 
)
static

Definition at line 262 of file wtp.c.

References wtp_tpi::data, gwlist_get(), gwlist_len(), octstr_get_bits(), wtp_pdu::options, TPI_PSN, wtp_tpi::type, wtp_pdu::u, wap_addr_tuple_duplicate(), and wap_event_create.

Referenced by unpack_wdp_datagram_real().

263 {
264  WAPEvent *event;
265  WTP_TPI *tpi;
266  int i, num_tpis;
267 
268  event = wap_event_create(RcvAck);
269  event->u.RcvAck.tid = pdu->u.Ack.tid;
270  event->u.RcvAck.tid_ok = pdu->u.Ack.tidverify;
271  event->u.RcvAck.rid = pdu->u.Ack.rid;
272  event->u.RcvAck.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);
273 
274  /* Set default to 0 because Ack on 1 piece message has no tpi */
275  event->u.RcvAck.psn = 0;
276  num_tpis = gwlist_len(pdu->options);
277 
278  for (i = 0; i < num_tpis; i++) {
279  tpi = gwlist_get(pdu->options, i);
280  if (tpi->type == TPI_PSN) {
281  event->u.RcvAck.psn = octstr_get_bits(tpi->data,0,8);
282  break;
283  }
284  }
285 
286  return event;
287 }
List * options
Definition: wtp_pdu.h:85
long gwlist_len(List *list)
Definition: list.c:166
Definition: wtp.h:174
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * data
Definition: wtp_pdu.h:72
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
int type
Definition: wtp_pdu.h:71
long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
Definition: octstr.c:1801
union wtp_pdu::@107 u
#define wap_event_create(type)
Definition: wap_events.h:107
static WAPEvent * unpack_invoke ( WTP_PDU pdu,
WAPAddrTuple addr_tuple 
)
static

Definition at line 207 of file wtp.c.

References octstr_duplicate, wtp_pdu::u, wap_addr_tuple_duplicate(), and wap_event_create.

Referenced by unpack_wdp_datagram_real().

208 {
209  WAPEvent *event;
210 
211  event = wap_event_create(RcvInvoke);
212  event->u.RcvInvoke.user_data =
213  octstr_duplicate(pdu->u.Invoke.user_data);
214  event->u.RcvInvoke.tcl = pdu->u.Invoke.class;
215  event->u.RcvInvoke.tid = pdu->u.Invoke.tid;
216  event->u.RcvInvoke.tid_new = pdu->u.Invoke.tidnew;
217  event->u.RcvInvoke.rid = pdu->u.Invoke.rid;
218  event->u.RcvInvoke.up_flag = pdu->u.Invoke.uack;
219  event->u.RcvInvoke.no_cache_supported = 0;
220  event->u.RcvInvoke.version = pdu->u.Invoke.version;
221  event->u.RcvInvoke.gtr = pdu->u.Invoke.gtr;
222  event->u.RcvInvoke.ttr = pdu->u.Invoke.ttr;
223  event->u.RcvInvoke.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);
224 
225  return event;
226 }
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
union wtp_pdu::@107 u
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
static WAPEvent * unpack_negative_ack ( WTP_PDU pdu,
WAPAddrTuple addr_tuple 
)
static

Definition at line 289 of file wtp.c.

References octstr_duplicate, wtp_pdu::u, wap_addr_tuple_duplicate(), and wap_event_create.

Referenced by unpack_wdp_datagram_real().

290 {
291  WAPEvent *event;
292 
293  event = wap_event_create(RcvNegativeAck);
294  event->u.RcvNegativeAck.tid = pdu->u.Negative_ack.tid;
295  event->u.RcvNegativeAck.rid = pdu->u.Negative_ack.rid;
296  event->u.RcvNegativeAck.nmissing = pdu->u.Negative_ack.nmissing;
297  event->u.RcvNegativeAck.missing = octstr_duplicate(pdu->u.Negative_ack.missing);
298  event->u.RcvNegativeAck.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);
299 
300  return event;
301 }
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
union wtp_pdu::@107 u
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
static WAPEvent * unpack_result ( WTP_PDU pdu,
WAPAddrTuple addr_tuple 
)
static

Definition at line 246 of file wtp.c.

References octstr_duplicate, wtp_pdu::u, wap_addr_tuple_duplicate(), and wap_event_create.

Referenced by unpack_wdp_datagram_real().

247 {
248  WAPEvent *event;
249 
250  event = wap_event_create(RcvResult);
251  event->u.RcvResult.user_data =
252  octstr_duplicate(pdu->u.Result.user_data);
253  event->u.RcvResult.tid = pdu->u.Result.tid;
254  event->u.RcvResult.rid = pdu->u.Result.rid;
255  event->u.RcvResult.gtr = pdu->u.Result.gtr;
256  event->u.RcvResult.ttr = pdu->u.Result.ttr;
257  event->u.RcvResult.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);
258 
259  return event;
260 }
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
union wtp_pdu::@107 u
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
static WAPEvent * unpack_segmented_invoke ( WTP_PDU pdu,
WAPAddrTuple addr_tuple 
)
static

Definition at line 228 of file wtp.c.

References octstr_duplicate, wtp_pdu::u, wap_addr_tuple_duplicate(), and wap_event_create.

Referenced by unpack_wdp_datagram_real().

229 {
230  WAPEvent *event;
231 
232  event = wap_event_create(RcvSegInvoke);
233  event->u.RcvSegInvoke.user_data =
234  octstr_duplicate(pdu->u.Segmented_invoke.user_data);
235  event->u.RcvSegInvoke.tid = pdu->u.Segmented_invoke.tid;
236  event->u.RcvSegInvoke.rid = pdu->u.Segmented_invoke.rid;
237  event->u.RcvSegInvoke.no_cache_supported = 0;
238  event->u.RcvSegInvoke.gtr = pdu->u.Segmented_invoke.gtr;
239  event->u.RcvSegInvoke.ttr = pdu->u.Segmented_invoke.ttr;
240  event->u.RcvSegInvoke.psn = pdu->u.Segmented_invoke.psn;
241  event->u.RcvSegInvoke.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);
242 
243  return event;
244 }
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
union wtp_pdu::@107 u
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
WAPEvent * unpack_wdp_datagram_real ( WAPEvent datagram)
static

Definition at line 342 of file wtp.c.

References debug(), error(), gw_assert(), pack_error(), truncated_datagram(), wtp_pdu::type, WAPEvent::type, WAPEvent::u, unpack_abort(), unpack_ack(), unpack_invoke(), unpack_negative_ack(), unpack_result(), unpack_segmented_invoke(), wap_event_assert(), wap_event_destroy(), wap_event_dump(), warning(), wtp_event_is_for_responder(), wtp_pdu_destroy(), and wtp_pdu_unpack().

Referenced by wtp_unpack_wdp_datagram().

343 {
344  WTP_PDU *pdu;
345  WAPEvent *event;
346  Octstr *data;
347 
348  gw_assert(datagram->type == T_DUnitdata_Ind);
349 
350  data = datagram->u.T_DUnitdata_Ind.user_data;
351 
352  if (truncated_datagram(datagram)) {
353  warning(0, "WTP: got a truncated datagram, ignoring");
354  return NULL;
355  }
356 
357  pdu = wtp_pdu_unpack(data);
358 
359  /*
360  * wtp_pdu_unpack returned NULL, we have send here a rcv error event,
361  * but now we silently drop the packet. Because we can't figure out
362  * in the pack_error() call if the TID value and hence the direction
363  * inditation is really for initiator or responder.
364  */
365  if (pdu == NULL) {
366  error(0, "WTP: cannot unpack pdu, dropping packet.");
367  return NULL;
368  }
369 
370  event = NULL;
371 
372  switch (pdu->type) {
373 
374  case Invoke:
375  event = unpack_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
376  /* if an WTP initiator gets invoke, it would be an illegal pdu. */
377  if (!wtp_event_is_for_responder(event)){
378  debug("wap.wtp", 0, "WTP: Invoke when initiator. Message was");
379  wap_event_destroy(event);
380  event = pack_error(datagram);
381  }
382  break;
383 
384  case Segmented_invoke:
385  event = unpack_segmented_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
386  break;
387 
388  case Result:
389  event = unpack_result(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
390  /* if an WTP responder gets result, it would be an illegal pdu. */
391  if (wtp_event_is_for_responder(event)){
392  debug("wap.wtp", 0, "WTP: Result when responder. Message was");
393  wap_event_destroy(event);
394  event = pack_error(datagram);
395  }
396  break;
397 
398  case Ack:
399  event = unpack_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
400  break;
401 
402  case Negative_ack:
403  event = unpack_negative_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
404  break;
405 
406  case Abort:
407  event = unpack_abort(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
408  break;
409 
410  default:
411  event = pack_error(datagram);
412  debug("wap.wtp", 0, "WTP: Unhandled PDU type. Message was");
413  wap_event_dump(datagram);
414  return event;
415  }
416 
417  wtp_pdu_destroy(pdu);
418 
419  wap_event_assert(event);
420  return event;
421 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int type
Definition: wtp_pdu.h:84
static WAPEvent * unpack_segmented_invoke(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
Definition: wtp.c:228
void wap_event_dump(WAPEvent *event)
Definition: wap_events.c:181
static WAPEvent * pack_error(WAPEvent *datagram)
Definition: wtp.c:316
void wap_event_assert(WAPEvent *event)
Definition: wap_events.c:220
static WAPEvent * unpack_invoke(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
Definition: wtp.c:207
int wtp_event_is_for_responder(WAPEvent *event)
Definition: wtp.c:156
static WAPEvent * unpack_ack(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
Definition: wtp.c:262
WTP_PDU * wtp_pdu_unpack(Octstr *data)
Definition: wtp_pdu.c:284
void warning(int err, const char *fmt,...)
Definition: log.c:624
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
static WAPEvent * unpack_abort(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
Definition: wtp.c:303
static WAPEvent * unpack_negative_ack(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
Definition: wtp.c:289
static int truncated_datagram(WAPEvent *event)
Definition: wtp.c:195
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
WAPEventName type
Definition: wap_events.h:88
void wtp_pdu_destroy(WTP_PDU *pdu)
Definition: wtp_pdu.c:104
union WAPEvent::@87 u
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
static WAPEvent * unpack_result(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
Definition: wtp.c:246
int wtp_event_is_for_responder ( WAPEvent event)

Definition at line 156 of file wtp.c.

References error(), INITIATOR_TID_LIMIT, WAPEvent::type, and wap_event_dump().

Referenced by unpack_wdp_datagram_real(), wap_dispatch_datagram(), and wtp_event_dump().

157 {
158 
159  switch(event->type){
160 
161  case RcvInvoke:
162  return event->u.RcvInvoke.tid < INITIATOR_TID_LIMIT;
163 
164  case RcvSegInvoke:
165  return event->u.RcvSegInvoke.tid < INITIATOR_TID_LIMIT;
166 
167  case RcvResult:
168  return event->u.RcvResult.tid < INITIATOR_TID_LIMIT;
169 
170  case RcvAck:
171  return event->u.RcvAck.tid < INITIATOR_TID_LIMIT;
172 
173  case RcvNegativeAck:
174  return event->u.RcvNegativeAck.tid < INITIATOR_TID_LIMIT;
175 
176  case RcvAbort:
177  return event->u.RcvAbort.tid < INITIATOR_TID_LIMIT;
178 
179  case RcvErrorPDU:
180  return event->u.RcvErrorPDU.tid < INITIATOR_TID_LIMIT;
181 
182  default:
183  error(1, "Received an erroneous PDU corresponding an event");
184  wap_event_dump(event);
185  return -1;
186  }
187 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define INITIATOR_TID_LIMIT
Definition: wtp.h:183
void wap_event_dump(WAPEvent *event)
Definition: wap_events.c:181
WAPEventName type
Definition: wap_events.h:88
List* wtp_unpack_wdp_datagram ( WAPEvent datagram)

Definition at line 98 of file wtp.c.

References concatenated_message(), gw_assert(), GW_WARNING, gwlist_append(), gwlist_create, octstr_copy, octstr_delete(), octstr_destroy(), octstr_dump, octstr_duplicate, octstr_get_bits(), octstr_get_char(), octstr_len(), WAPEvent::type, WAPEvent::u, unpack_wdp_datagram_real(), wap_event_assert(), wap_event_destroy(), wap_event_duplicate(), and warning().

Referenced by wap_dispatch_datagram(), and wtp_event_dump().

99 {
100  List *events = NULL;
101  WAPEvent *event = NULL;
102  WAPEvent *subdgram = NULL;
103  Octstr *data = NULL;
104  long pdu_len;
105 
106  gw_assert(datagram->type == T_DUnitdata_Ind);
107 
108  events = gwlist_create();
109 
110  if (concatenated_message(datagram->u.T_DUnitdata_Ind.user_data)) {
111  data = octstr_duplicate(datagram->u.T_DUnitdata_Ind.user_data);
112  octstr_delete(data, 0, 1);
113 
114  while (octstr_len(data) != 0) {
115 
116  if (octstr_get_bits(data, 0, 1) == 0) {
117  pdu_len = octstr_get_char(data, 0);
118  octstr_delete(data, 0, 1);
119  } else {
120  pdu_len = octstr_get_bits(data, 1, 15);
121  octstr_delete(data, 0, 2);
122  }
123 
124  subdgram = wap_event_duplicate(datagram);
125  octstr_destroy(subdgram->u.T_DUnitdata_Ind.user_data);
126  subdgram->u.T_DUnitdata_Ind.user_data = octstr_copy(data, 0, pdu_len);
127  wap_event_assert(subdgram);
128  if ((event = unpack_wdp_datagram_real(subdgram)) != NULL) {
129  wap_event_assert(event);
130  gwlist_append(events, event);
131  }
132  octstr_delete(data, 0, pdu_len);
133  wap_event_destroy(subdgram);
134  }
135 
136  octstr_destroy(data);
137 
138  } else if ((event = unpack_wdp_datagram_real(datagram)) != NULL) {
139  wap_event_assert(event);
140  gwlist_append(events, event);
141  } else {
142  warning(0, "WTP: Dropping unhandled datagram data:");
143  octstr_dump(datagram->u.T_DUnitdata_Ind.user_data, 0, GW_WARNING);
144  }
145 
146  return events;
147 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
static int concatenated_message(Octstr *user_data)
Definition: wtp.c:434
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
Definition: octstr.c:1801
void wap_event_assert(WAPEvent *event)
Definition: wap_events.c:220
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
static WAPEvent * unpack_wdp_datagram_real(WAPEvent *datagram)
Definition: wtp.c:342
Definition: log.h:69
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
WAPEvent * wap_event_duplicate(WAPEvent *event)
Definition: wap_events.c:135
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
WAPEventName type
Definition: wap_events.h:88
#define gwlist_create()
Definition: list.h:136
union WAPEvent::@87 u
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
Definition: list.c:102
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.