Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
test_cimd2.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "gwlib/gwlib.h"

Go to the source code of this file.

Typedefs

typedef void(* packet_handler) (Octstr *, Octstr *, int)
 

Enumerations

enum  { TIMESTAMP_MAXLEN = 13 }
 
enum  ACT { ACT_listen = 0, ACT_reply = 1, ACT_deliver = 2, ACT_flood = 3 }
 
enum  SPEW { SPEW_nothing = 0, SPEW_binary = 1, SPEW_characters = 2, SPEW_packets = 3 }
 
enum  LOG { LOG_nothing = 0, LOG_data = 1, LOG_packets = 2, LOG_sms = 3 }
 
enum  CHK {
  CHK_nothing = 0, CHK_packets = 1, CHK_sums = 2, CHK_protocol = 3,
  CHK_sms = 4
}
 
enum  { OUTBUFFER_LIMIT = 65536 }
 
enum  { EVIL_BUFSIZE = 1021 }
 
enum  CHARS {
  STX = 2, ETX = 3, TAB = 9, LF = 10,
  CR = 13
}
 

Functions

static void usage (FILE *out)
 
static void pretty_print (unsigned char *data, size_t length)
 
static void read_data (Octstr *in, int fd)
 
static void write_data (Octstr *out, int fd)
 
static void gen_message (Octstr *out)
 
static long gen_data (Octstr *out)
 
static void make_timestamp (unsigned char *buf, time_t fortime)
 
static void send_packet (Octstr *out, int opcode, int sequence,...)
 
static void send_error (Octstr *out, int opcode, int sequence, unsigned char *errorcode, unsigned char *errortext)
 
static int eat_char (Octstr *packet, int ch)
 
static Octstreat_string_parm (Octstr *packet, int parm, int maxlen)
 
static long eat_number (Octstr *ostr)
 
static long eat_int_parm (Octstr *packet, int parm, int maxlen)
 
static void eat_checksum (Octstr *packet)
 
static void handle_login (Octstr *packet, Octstr *out, int sequence)
 
static void handle_logout (Octstr *packet, Octstr *out, int sequence)
 
static void handle_submit (Octstr *packet, Octstr *out, int sequence)
 
static void handle_enquire (Octstr *packet, Octstr *out, int sequence)
 
static void handle_delivery_request (Octstr *packet, Octstr *out, int sequence)
 
static void handle_cancel (Octstr *packet, Octstr *out, int sequence)
 
static void handle_set (Octstr *packet, Octstr *out, int sequence)
 
static void handle_get (Octstr *packet, Octstr *out, int sequence)
 
static void handle_alive (Octstr *packet, Octstr *out, int sequence)
 
static void handle_deliver_response (Octstr *packet, Octstr *out, int sequence)
 
static void handle_deliver_status_report_response (Octstr *packet, Octstr *out, int sequence)
 
static void handle_alive_response (Octstr *packet, Octstr *out, int sequence)
 
static void handle_nack (Octstr *packet, Octstr *out, int sequence)
 
static void parse_packet (Octstr *packet, Octstr *out)
 
static void parse_data (Octstr *in, Octstr *out)
 
static void random_address (unsigned char *buf, int size)
 
static void random_message (unsigned char *buf, int size)
 
static void random_hex (unsigned char *buf, int size)
 
static void main_loop (void)
 
static int wait_for_client (int port)
 
int main (int argc, char *argv[])
 

Variables

unsigned char * progname
 
unsigned char * username = "foo"
 
unsigned char * password = "bar"
 
int port = 6789
 
unsigned char * intro = ""
 
int activity = ACT_listen
 
int spew = SPEW_nothing
 
int logging = LOG_nothing
 
int checking = CHK_nothing
 
int max_deliveries = -1
 
int deliveries = 0
 
time_t start_time = 0
 
int sockfd = -1
 
Octstrinbuffer
 
Octstroutbuffer
 
int awaiting_response = 0
 
struct {
   int   opcode
 
   packet_handler   handler
 
handlers []
 
struct {
   unsigned char *   option
 
   void *   location
 
   int   number
 
options []
 

Typedef Documentation

typedef void(* packet_handler) (Octstr *, Octstr *, int)

Definition at line 766 of file test_cimd2.c.

Enumeration Type Documentation

anonymous enum
Enumerator
TIMESTAMP_MAXLEN 

Definition at line 94 of file test_cimd2.c.

anonymous enum
Enumerator
OUTBUFFER_LIMIT 

Definition at line 151 of file test_cimd2.c.

151 { OUTBUFFER_LIMIT = 65536 };
anonymous enum
Enumerator
EVIL_BUFSIZE 

Definition at line 156 of file test_cimd2.c.

156 { EVIL_BUFSIZE = 1021 };
enum ACT
Enumerator
ACT_listen 
ACT_reply 
ACT_deliver 
ACT_flood 

Definition at line 107 of file test_cimd2.c.

107  {
108  ACT_listen = 0,
109  ACT_reply = 1,
110  ACT_deliver = 2,
111  ACT_flood = 3
112 };
enum CHARS
Enumerator
STX 
ETX 
TAB 
LF 
CR 

Definition at line 159 of file test_cimd2.c.

159  {
160  STX = 2,
161  ETX = 3,
162  TAB = 9,
163  LF = 10,
164  CR = 13
165 };
Definition: test_cimd2.c:164
Definition: test_cimd2.c:163
enum CHK
Enumerator
CHK_nothing 
CHK_packets 
CHK_sums 
CHK_protocol 
CHK_sms 

Definition at line 128 of file test_cimd2.c.

128  {
129  CHK_nothing = 0,
130  CHK_packets = 1,
131  CHK_sums = 2,
132  CHK_protocol = 3,
133  CHK_sms = 4
134 };
enum LOG
Enumerator
LOG_nothing 
LOG_data 
LOG_packets 
LOG_sms 

Definition at line 121 of file test_cimd2.c.

121  {
122  LOG_nothing = 0,
123  LOG_data = 1,
124  LOG_packets = 2,
125  LOG_sms = 3
126 };
enum SPEW
Enumerator
SPEW_nothing 
SPEW_binary 
SPEW_characters 
SPEW_packets 

Definition at line 114 of file test_cimd2.c.

114  {
115  SPEW_nothing = 0,
116  SPEW_binary = 1,
117  SPEW_characters = 2,
118  SPEW_packets = 3
119 };

Function Documentation

static int eat_char ( Octstr packet,
int  ch 
)
static

Definition at line 368 of file test_cimd2.c.

References octstr_delete(), and octstr_get_char().

Referenced by parse_packet().

368  {
369  if (octstr_get_char(packet, 0) == ch) {
370  octstr_delete(packet, 0, 1);
371  return 0;
372  }
373  return -1;
374 }
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static void eat_checksum ( Octstr packet)
static

Definition at line 429 of file test_cimd2.c.

References octstr_delete(), octstr_get_char(), octstr_len(), and TAB.

Referenced by parse_packet().

429  {
430  int len;
431  int ch1, ch2, ch3;
432 
433  len = octstr_len(packet);
434 
435  if (len < 3)
436  return;
437 
438  ch1 = octstr_get_char(packet, len - 3);
439  ch2 = octstr_get_char(packet, len - 2);
440  ch3 = octstr_get_char(packet, len - 1);
441 
442  if (isxdigit(ch3) && isxdigit(ch2) && ch1 == TAB)
443  octstr_delete(packet, len - 3, 3);
444 }
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static long eat_int_parm ( Octstr packet,
int  parm,
int  maxlen 
)
static

Definition at line 413 of file test_cimd2.c.

References eat_number(), eat_string_parm(), octstr_destroy(), and octstr_len().

Referenced by handle_cancel(), handle_delivery_request(), handle_get(), and handle_submit().

413  {
414  Octstr *value;
415  long result;
416 
417  value = eat_string_parm(packet, parm, maxlen);
418  if (!value)
419  return INT_MIN;
420 
421  result = eat_number(value);
422  if (octstr_len(value) > 0)
423  result = INT_MIN;
424 
425  octstr_destroy(value);
426  return result;
427 }
static long eat_number(Octstr *ostr)
Definition: test_cimd2.c:401
Definition: seewbmp.c:154
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
int maxlen
Definition: smsc_cimd2.c:214
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static Octstr * eat_string_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:376
static long eat_number ( Octstr ostr)
static

Definition at line 401 of file test_cimd2.c.

References octstr_delete(), and octstr_parse_long().

Referenced by eat_int_parm(), and parse_packet().

401  {
402  long result;
403  long pos;
404 
405  pos = octstr_parse_long(&result, ostr, 0, 10);
406  if (pos < 0)
407  return INT_MIN;
408 
409  octstr_delete(ostr, 0, pos);
410  return result;
411 }
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:747
static Octstr* eat_string_parm ( Octstr packet,
int  parm,
int  maxlen 
)
static

Definition at line 376 of file test_cimd2.c.

References octstr_copy, octstr_delete(), octstr_destroy(), octstr_format(), octstr_len(), octstr_search(), octstr_search_char(), start, and TAB.

Referenced by eat_int_parm(), handle_cancel(), handle_enquire(), handle_login(), handle_set(), and handle_submit().

376  {
377  long start, datastart;
378  long tab;
379  Octstr *result;
380  Octstr *parmheader;
381 
382  parmheader = octstr_format("%c%03d:", TAB, parm);
383  start = octstr_search(packet, parmheader, 0);
384  if (start < 0) {
385  octstr_destroy(parmheader);
386  return NULL;
387  }
388  datastart = start + octstr_len(parmheader);
389 
390  tab = octstr_search_char(packet, TAB, datastart + 1);
391  if (tab < 0) {
392  tab = octstr_len(packet);
393  }
394 
395  result = octstr_copy(packet, datastart, tab - datastart);
396  octstr_delete(packet, start, tab - start);
397  octstr_destroy(parmheader);
398  return result;
399 }
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1068
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
Definition: seewbmp.c:154
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static int start
static long gen_data ( Octstr out)
static

Definition at line 275 of file test_cimd2.c.

References ACT_deliver, ACT_flood, activity, deliveries, EVIL_BUFSIZE, gen_message(), interval, max_deliveries, octstr_append_data(), spew, and SPEW_binary.

Referenced by main_loop().

275  {
276  unsigned char buf[EVIL_BUFSIZE];
277  size_t i;
278  long interval = -1;
279  static int last_sms; /* Used by ACT_deliver */
280  time_t now;
281 
283  switch (activity) {
284  case ACT_deliver:
285  now = time(NULL);
286  if (last_sms == 0)
287  last_sms = now;
288  while (last_sms < now) {
289  if (random() % 7 == 1) {
290  gen_message(out);
291  last_sms = now;
292  } else
293  last_sms++;
294  }
295  interval = 1000000;
296  break;
297  case ACT_flood:
298  gen_message(out);
299  break;
300  }
301  }
302 
303  switch (spew) {
304  case SPEW_binary:
305  for (i = 0; i < sizeof(buf); i++) {
306  buf[i] = random() % 256;
307  }
308  octstr_append_data(out, buf, sizeof(buf));
309  break;
310  }
311 
312  return interval;
313 }
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1495
int deliveries
Definition: test_cimd2.c:142
double interval
Definition: fakewap.c:234
static void gen_message(Octstr *out)
Definition: test_cimd2.c:886
int activity
Definition: test_cimd2.c:136
int max_deliveries
Definition: test_cimd2.c:141
int spew
Definition: test_cimd2.c:137
static void gen_message ( Octstr out)
static

Definition at line 886 of file test_cimd2.c.

References awaiting_response, LOG_packets, logging, make_timestamp(), random_address(), random_hex(), random_message(), send_packet(), and TIMESTAMP_MAXLEN.

Referenced by gen_data().

886  {
887  static int send_seq = 0;
888  unsigned char dest[21];
889  unsigned char orig[21];
890  unsigned char scts[TIMESTAMP_MAXLEN];
891  unsigned char message[481];
892  unsigned char udh[281];
893 
894  if (awaiting_response == 1)
895  return;
896 
897  random_address(dest, sizeof(dest));
898  random_address(orig, sizeof(orig));
899  make_timestamp(scts, time(NULL));
900  random_message(message, sizeof(message));
901  if (random() % 2 == 0)
902  random_hex(udh, sizeof(udh));
903  else
904  *udh = 0;
905 
906  if (logging == LOG_packets)
907  printf("SND: Deliver message (random)\n");
908 
909  if (*udh) {
910  send_packet(out, 20, send_seq,
911  21, dest,
912  23, orig,
913  60, scts,
914  32, udh,
915  33, message,
916  0);
917  } else {
918  send_packet(out, 20, send_seq,
919  21, dest,
920  23, orig,
921  60, scts,
922  33, message,
923  0);
924  }
925 
926  send_seq += 2;
927  if (send_seq > 255)
928  send_seq = 0;
929 
930  awaiting_response = 1;
931 }
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
int awaiting_response
Definition: test_cimd2.c:317
static void random_hex(unsigned char *buf, int size)
Definition: test_cimd2.c:869
static void random_address(unsigned char *buf, int size)
Definition: test_cimd2.c:846
static void make_timestamp(unsigned char *buf, time_t fortime)
Definition: test_cimd2.c:320
static void random_message(unsigned char *buf, int size)
Definition: test_cimd2.c:856
int logging
Definition: test_cimd2.c:138
static void handle_alive ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 723 of file test_cimd2.c.

References LOG_packets, logging, and send_packet().

723  {
724  if (logging == LOG_packets)
725  printf("RCV: Alive?\n");
726  if (logging == LOG_packets)
727  printf("SND: Alive.\n");
728  send_packet(out, 90, sequence, 0);
729 }
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
int logging
Definition: test_cimd2.c:138
static void handle_alive_response ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 751 of file test_cimd2.c.

References awaiting_response, LOG_packets, and logging.

751  {
752  awaiting_response = 0;
753  if (logging == LOG_packets)
754  printf("RCV: Alive.\n");
755  /* No need to respond to a response */
756 }
int awaiting_response
Definition: test_cimd2.c:317
int logging
Definition: test_cimd2.c:138
static void handle_cancel ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 659 of file test_cimd2.c.

References eat_int_parm(), eat_string_parm(), LOG_packets, logging, octstr_get_cstr, send_error(), and send_packet().

659  {
660  long mode = eat_int_parm(packet, 59, 1);
661  Octstr *timestamp = eat_string_parm(packet, 60, 12);
662  Octstr *destination = eat_string_parm(packet, 21, 20);
663 
664  if (logging == LOG_packets) {
665  printf("RCV: Cancel");
666  if (mode != INT_MIN)
667  printf(", mode %ld", mode);
668  if (destination)
669  printf(", dest '%s'", octstr_get_cstr(destination));
670  if (timestamp)
671  printf(", time '%s'", octstr_get_cstr(timestamp));
672  printf("\n");
673  }
674 
675  if (mode < 0 || mode > 2)
676  send_error(out, 56, sequence, "602", "bad mode");
677  else {
678  if (logging == LOG_packets)
679  printf("SND: OK\n");
680  send_packet(out, 56, sequence, 0);
681  }
682 }
static long eat_int_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:413
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: octstr.c:118
static Octstr * eat_string_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:376
static void send_error(Octstr *out, int opcode, int sequence, unsigned char *errorcode, unsigned char *errortext)
Definition: test_cimd2.c:360
int logging
Definition: test_cimd2.c:138
static void handle_deliver_response ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 731 of file test_cimd2.c.

References awaiting_response, deliveries, LOG_packets, logging, max_deliveries, and start_time.

731  {
732  awaiting_response = 0;
733  if (logging == LOG_packets)
734  printf("RCV: Deliver response\n");
735  deliveries++;
736  if (max_deliveries > 0 && deliveries == max_deliveries) {
737  time_t elapsed = time(NULL) - start_time;
738  printf("LOG: %ld deliveries in %ld seconds\n",
739  (long) max_deliveries, (long) elapsed);
740  }
741  /* No need to respond to a response */
742 }
int awaiting_response
Definition: test_cimd2.c:317
int deliveries
Definition: test_cimd2.c:142
int max_deliveries
Definition: test_cimd2.c:141
int logging
Definition: test_cimd2.c:138
time_t start_time
Definition: test_cimd2.c:143
static void handle_deliver_status_report_response ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 744 of file test_cimd2.c.

References awaiting_response, LOG_packets, and logging.

744  {
745  awaiting_response = 0;
746  if (logging == LOG_packets)
747  printf("RCV: Deliver status report response\n");
748  /* No need to respond to a response */
749 }
int awaiting_response
Definition: test_cimd2.c:317
int logging
Definition: test_cimd2.c:138
static void handle_delivery_request ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 614 of file test_cimd2.c.

References eat_int_parm(), LOG_packets, logging, send_error(), and send_packet().

614  {
615  long mode = eat_int_parm(packet, 68, 1);
616 
617  if (logging == LOG_packets) {
618  switch (mode) {
619  case 0: printf("RCV: Delivery request, messages waiting?\n");
620  break;
621  case 1: printf("RCV: Delivery request, one message\n");
622  break;
623  case 2: printf("RCV: Delivery request, all messages\n");
624  break;
625  case INT_MIN:
626  printf("RCV: Delivery request, no mode\n");
627  break;
628  default:
629  printf("RCV: Delivery request, mode %ld\n", mode);
630  }
631  }
632 
633  if (mode == INT_MIN)
634  mode = 1;
635 
636  switch (mode) {
637  case 0:
638  if (logging == LOG_packets)
639  printf("SND: Respond: 0 messages\n");
640  send_packet(out, 55, sequence,
641  66, "0",
642  0);
643  break;
644 
645  case 1:
646  send_error(out, 55, sequence, "500", "no messages available");
647  break;
648 
649  case 2:
650  send_error(out, 55, sequence, "500", "no messages available");
651  break;
652 
653  default:
654  send_error(out, 55, sequence, "501", "bad mode");
655  break;
656  }
657 }
static long eat_int_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:413
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
static void send_error(Octstr *out, int opcode, int sequence, unsigned char *errorcode, unsigned char *errortext)
Definition: test_cimd2.c:360
int logging
Definition: test_cimd2.c:138
static void handle_enquire ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 588 of file test_cimd2.c.

References eat_string_parm(), LOG_packets, logging, octstr_destroy(), octstr_get_cstr, send_error(), and send_packet().

588  {
589  Octstr *dest_addr = eat_string_parm(packet, 21, 20);
590  Octstr *timestamp = eat_string_parm(packet, 60, 12);
591 
592  if (logging == LOG_packets)
593  printf("RCV: Enquire status, dest='%s', time='%s'\n",
594  dest_addr ? octstr_get_cstr(dest_addr) : "",
595  timestamp ? octstr_get_cstr(timestamp) : "");
596 
597  if (!dest_addr) {
598  send_error(out, 54, sequence, "400", "no destination");
599  } else if (!timestamp) {
600  send_error(out, 54, sequence, "401", "no timestamp");
601  } else {
602  if (logging == LOG_packets)
603  printf("SND: Respond: status unknown\n");
604  send_packet(out, 54, sequence,
605  21, octstr_get_cstr(dest_addr),
606  60, octstr_get_cstr(timestamp),
607  61, "0",
608  0);
609  }
610  octstr_destroy(dest_addr);
611  octstr_destroy(timestamp);
612 }
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
static Octstr * eat_string_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:376
static void send_error(Octstr *out, int opcode, int sequence, unsigned char *errorcode, unsigned char *errortext)
Definition: test_cimd2.c:360
int logging
Definition: test_cimd2.c:138
static void handle_get ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 702 of file test_cimd2.c.

References eat_int_parm(), LOG_packets, logging, make_timestamp(), number, send_error(), send_packet(), and TIMESTAMP_MAXLEN.

702  {
703  long number = eat_int_parm(packet, 500, 3);
704 
705  if (logging == LOG_packets)
706  printf("RCV: Get parameter #%ld\n", number);
707 
708  if (number == INT_MIN) {
709  send_error(out, 59, sequence, "900", "missing parameter");
710  } else if (number == 501) {
711  unsigned char buf[TIMESTAMP_MAXLEN];
712  make_timestamp(buf, time(NULL));
713  if (logging == LOG_packets)
714  printf("SND: OK, SMSC timestamp is '%s'\n", buf);
715  send_packet(out, 59, sequence,
716  501, buf,
717  0);
718  } else {
719  send_error(out, 59, sequence, "900", "unknown parameter");
720  }
721 }
static long eat_int_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:413
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
int number
Definition: test_cimd2.c:1002
static void make_timestamp(unsigned char *buf, time_t fortime)
Definition: test_cimd2.c:320
static void send_error(Octstr *out, int opcode, int sequence, unsigned char *errorcode, unsigned char *errortext)
Definition: test_cimd2.c:360
int logging
Definition: test_cimd2.c:138
static void handle_login ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 446 of file test_cimd2.c.

References eat_string_parm(), LOG_packets, logging, octstr_create, octstr_destroy(), octstr_get_cstr, octstr_str_compare(), password, send_error(), send_packet(), and username.

446  {
447  Octstr *user = eat_string_parm(packet, 10, 32);
448  Octstr *pass = eat_string_parm(packet, 11, 32);
449 
450  if (user == NULL)
451  user = octstr_create("");
452  if (pass == NULL)
453  pass = octstr_create("");
454 
455  if (logging == LOG_packets)
456  printf("RCV: Login user '%s', password '%s'\n",
457  octstr_get_cstr(user), octstr_get_cstr(pass));
458 
459  if (octstr_str_compare(user, username) == 0 &&
460  octstr_str_compare(pass, password) == 0) {
461  if (logging == LOG_packets)
462  printf("SND: Login OK\n");
463  send_packet(out, 51, sequence, 0);
464  } else {
465  send_error(out, 51, sequence, "100", "invalid login");
466  }
467 
468  octstr_destroy(user);
469  octstr_destroy(pass);
470 }
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned char * username
Definition: test_cimd2.c:99
unsigned char * password
Definition: test_cimd2.c:100
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
static Octstr * eat_string_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:376
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
static void send_error(Octstr *out, int opcode, int sequence, unsigned char *errorcode, unsigned char *errortext)
Definition: test_cimd2.c:360
int logging
Definition: test_cimd2.c:138
static void handle_logout ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 472 of file test_cimd2.c.

References LOG_packets, logging, and send_packet().

472  {
473  if (logging == LOG_packets)
474  printf("RCV: Logout\n");
475  if (logging == LOG_packets)
476  printf("SND: Logout OK\n");
477  send_packet(out, 52, sequence, 0);
478 }
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
int logging
Definition: test_cimd2.c:138
static void handle_nack ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 758 of file test_cimd2.c.

References awaiting_response, LOG_packets, and logging.

758  {
759  awaiting_response = 0;
760  if (logging == LOG_packets)
761  printf("RCV: NACK\n");
762  /* TODO: We should retransmit if we get a nack, but there's
763  * no record of what request we sent. */
764 }
int awaiting_response
Definition: test_cimd2.c:317
int logging
Definition: test_cimd2.c:138
static void handle_set ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 685 of file test_cimd2.c.

References eat_string_parm(), LOG_packets, logging, octstr_get_cstr, and send_error().

685  {
686  Octstr *pass = eat_string_parm(packet, 11, 32);
687 
688  if (pass) {
689  if (logging == LOG_packets)
690  printf("RCV: Set password to '%s'\n",
691  octstr_get_cstr(pass));
692  send_error(out, 58, sequence,
693  "801", "changing password not allowed");
694  } else {
695  if (logging == LOG_packets)
696  printf("RCV: Set, unknown parameters\n");
697  send_error(out, 58, sequence, "3", "cannot set");
698  }
699 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: octstr.c:118
static Octstr * eat_string_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:376
static void send_error(Octstr *out, int opcode, int sequence, unsigned char *errorcode, unsigned char *errortext)
Definition: test_cimd2.c:360
int logging
Definition: test_cimd2.c:138
static void handle_submit ( Octstr packet,
Octstr out,
int  sequence 
)
static

Definition at line 480 of file test_cimd2.c.

References eat_int_parm(), eat_string_parm(), gwlist_append(), gwlist_create, gwlist_destroy(), gwlist_get(), gwlist_len(), LOG_packets, logging, make_timestamp(), octstr_destroy(), octstr_destroy_item(), octstr_get_cstr, send_error(), send_packet(), text, and TIMESTAMP_MAXLEN.

480  {
481  Octstr *dest_addr = eat_string_parm(packet, 21, 20);
482  Octstr *orig_addr = eat_string_parm(packet, 23, 20);
483  long DCS = eat_int_parm(packet, 30, 3);
484  Octstr *UDH = eat_string_parm(packet, 32, 280);
485  Octstr *text = eat_string_parm(packet, 33, 480);
486  Octstr *textb = eat_string_parm(packet, 34, 280);
487  long valid_rel = eat_int_parm(packet, 50, 3);
488  Octstr *valid_abs = eat_string_parm(packet, 51, 12);
489  long proto_id = eat_int_parm(packet, 52, 3);
490  long delivery_rel = eat_int_parm(packet, 53, 3);
491  Octstr *delivery_abs = eat_string_parm(packet, 54, 12);
492  long reply_path = eat_int_parm(packet, 55, 1);
493  long SRR = eat_int_parm(packet, 56, 2);
494  long cancel = eat_int_parm(packet, 58, 1);
495  long tariff_class = eat_int_parm(packet, 64, 2);
496  long service_desc = eat_int_parm(packet, 65, 1);
497  long priority = eat_int_parm(packet, 67, 1);
498  List *other_dests = gwlist_create();
499  Octstr *tmp;
500 
501  while ((tmp = eat_string_parm(packet, 21, 20)))
502  gwlist_append(other_dests, tmp);
503 
504  if (logging == LOG_packets) {
505  int i;
506  printf("RCV: Submit to %s", octstr_get_cstr(dest_addr));
507  for (i = 0; i < gwlist_len(other_dests); i++) {
508  printf(", %s",
509  octstr_get_cstr(gwlist_get(other_dests, i)));
510  }
511  printf("\n");
512 
513  if (orig_addr)
514  printf(" From: %s\n", octstr_get_cstr(orig_addr));
515  if (DCS > INT_MIN)
516  printf(" Data coding: %ld\n", DCS);
517  if (UDH)
518  printf(" User data header: %s\n",
519  octstr_get_cstr(UDH));
520  if (text)
521  printf(" Text: %s\n", octstr_get_cstr(text));
522  if (textb)
523  printf(" Text (binary): %s\n",
524  octstr_get_cstr(textb));
525  if (valid_rel > INT_MIN)
526  printf(" Validity period: %ld (relative)\n",
527  valid_rel);
528  if (valid_abs)
529  printf(" Validity period: %s (absolute)\n",
530  octstr_get_cstr(valid_abs));
531  if (proto_id > INT_MIN)
532  printf(" Protocol ID: %ld\n", proto_id);
533  if (delivery_rel > INT_MIN)
534  printf(" First delivery: %ld (relative)\n",
535  delivery_rel);
536  if (delivery_abs)
537  printf(" First delivery: %s (absolute)\n",
538  octstr_get_cstr(delivery_abs));
539  if (reply_path == 0)
540  printf(" Reply path disabled\n");
541  else if (reply_path == 1)
542  printf(" Reply path enabled\n");
543  else if (reply_path > INT_MAX)
544  printf(" Reply path: %ld\n", reply_path);
545  if (SRR > INT_MAX)
546  printf(" Status report flags: %ld\n", SRR);
547  if (cancel == 0)
548  printf(" Cancel disabled\n");
549  else if (cancel == 1)
550  printf(" Cancel enabled\n");
551  else if (cancel > INT_MAX)
552  printf(" Cancel enabled: %ld\n", cancel);
553  if (tariff_class > INT_MAX)
554  printf(" Tariff class: %ld\n", tariff_class);
555  if (service_desc > INT_MAX)
556  printf(" Service description: %ld\n", service_desc);
557  if (priority > INT_MAX)
558  printf(" Priority: %ld\n", priority);
559  }
560 
561  if (!dest_addr) {
562  send_error(out, 53, sequence, "300", "no destination");
563  } else if (gwlist_len(other_dests) > 0) {
564  send_error(out, 53, sequence, "301", "too many destinations");
565  /* TODO: Report many other possible errors here */
566  } else {
567  unsigned char buf[TIMESTAMP_MAXLEN];
568 
569  make_timestamp(buf, time(NULL));
570  if (logging == LOG_packets)
571  printf("SND: Submit OK\n");
572  send_packet(out, 53, sequence,
573  21, octstr_get_cstr(dest_addr),
574  60, buf,
575  0);
576  }
577 
578  octstr_destroy(dest_addr);
579  octstr_destroy(orig_addr);
580  octstr_destroy(UDH);
581  octstr_destroy(text);
582  octstr_destroy(textb);
583  octstr_destroy(valid_abs);
584  octstr_destroy(delivery_abs);
585  gwlist_destroy(other_dests, octstr_destroy_item);
586 }
static long eat_int_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:413
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
char * text
Definition: smsc_cimd2.c:921
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
void octstr_destroy_item(void *os)
Definition: octstr.c:334
static void make_timestamp(unsigned char *buf, time_t fortime)
Definition: test_cimd2.c:320
Definition: octstr.c:118
static Octstr * eat_string_parm(Octstr *packet, int parm, int maxlen)
Definition: test_cimd2.c:376
#define gwlist_create()
Definition: list.h:136
static void send_error(Octstr *out, int opcode, int sequence, unsigned char *errorcode, unsigned char *errortext)
Definition: test_cimd2.c:360
int logging
Definition: test_cimd2.c:138
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
int main ( int  argc,
char *  argv[] 
)

Definition at line 1053 of file test_cimd2.c.

References gwlib_init(), main_loop(), number, option, options, progname, sockfd, usage(), and wait_for_client().

1053  {
1054  int i;
1055  int opt;
1056 
1057  gwlib_init();
1058 
1059  progname = argv[0];
1060  srandom(0); /* Make "random" data reproducible */
1061 
1062  for (i = 1; i < argc; i++) {
1063  for (opt = 0; options[opt].option; opt++) {
1064  if (strcmp(argv[i], options[opt].option) == 0) {
1065  if (i + 1 >= argc) {
1066  fprintf(stderr, "%s: missing argument to %s",
1067  progname, argv[i]);
1068  exit(2);
1069  }
1070  if (options[opt].number) {
1071  * (int *) options[opt].location = atoi(argv[i+1]);
1072  } else {
1073  * (char **) options[opt].location = argv[i+1];
1074  }
1075  i++;
1076  break;
1077  }
1078  }
1079  if (options[opt].option)
1080  continue;
1081  if (strcmp(argv[i], "--help") == 0) {
1082  usage(stdout);
1083  exit(0);
1084  }
1085  if (argv[i][0] == '-') {
1086  fprintf(stderr, "%s: unknown option %s\n",
1087  progname, argv[i]);
1088  usage(stderr);
1089  exit(2);
1090  }
1091  }
1092 
1094  main_loop();
1095  return 0;
1096 }
Definition: http.c:1998
static void main_loop(void)
Definition: test_cimd2.c:935
int number
Definition: test_cimd2.c:1002
unsigned char * option
Definition: test_cimd2.c:1000
int sockfd
Definition: test_cimd2.c:145
static struct @78 options[]
void gwlib_init(void)
Definition: gwlib.c:78
static int wait_for_client(int port)
Definition: test_cimd2.c:1016
static void usage(FILE *out)
Definition: test_cimd2.c:167
unsigned char * progname
Definition: test_cimd2.c:96
static void main_loop ( void  )
static

Definition at line 935 of file test_cimd2.c.

References error(), gen_data(), interval, intro, octstr_create, octstr_len(), OUTBUFFER_LIMIT, parse_data(), read_data(), sockfd, start_time, warning(), and write_data().

Referenced by main().

935  {
936  fd_set readfds, writefds;
937  int n;
938  static int reported_outfull = 0;
939  int interval = -1;
940 
941  inbuffer = octstr_create("");
943  start_time = time(NULL);
944 
945  for (;;) {
947  interval = gen_data(outbuffer);
948  } else if (!reported_outfull) {
949  warning(0, "outbuffer getting full; waiting...");
950  reported_outfull = 1;
951  }
952 
953  FD_ZERO(&readfds);
954  FD_SET(sockfd, &readfds);
955 
956  if (octstr_len(outbuffer) > 0) {
957  FD_ZERO(&writefds);
958  FD_SET(sockfd, &writefds);
959  n = select(sockfd+1, &readfds, &writefds, NULL, NULL);
960  } else {
961  struct timeval tv;
962  struct timeval *tvp;
963 
964  if (interval >= 0) {
965  tv.tv_sec = 0;
966  tv.tv_usec = interval;
967  tvp = &tv;
968  } else {
969  tvp = NULL;
970  }
971  n = select(sockfd+1, &readfds, NULL, NULL, tvp);
972  }
973 
974  if (n < 0) {
975  if (errno == EINTR) {
976  warning(errno, "main loop, select");
977  continue;
978  }
979  error(errno, "main loop, select");
980  sleep(1);
981  continue;
982  }
983  if (n > 0) {
984  if (FD_ISSET(sockfd, &readfds)) {
987  }
988  if (octstr_len(outbuffer) > 0 &&
989  FD_ISSET(sockfd, &writefds)) {
991  }
993  reported_outfull = 0;
994  }
995  }
996  }
997 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static long gen_data(Octstr *out)
Definition: test_cimd2.c:275
Octstr * inbuffer
Definition: test_cimd2.c:147
Octstr * outbuffer
Definition: test_cimd2.c:148
unsigned char * intro
Definition: test_cimd2.c:105
static void read_data(Octstr *in, int fd)
Definition: test_cimd2.c:224
void warning(int err, const char *fmt,...)
Definition: log.c:624
#define octstr_create(cstr)
Definition: octstr.h:125
static void parse_data(Octstr *in, Octstr *out)
Definition: test_cimd2.c:817
double interval
Definition: fakewap.c:234
static void write_data(Octstr *out, int fd)
Definition: test_cimd2.c:244
int sockfd
Definition: test_cimd2.c:145
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
time_t start_time
Definition: test_cimd2.c:143
static void make_timestamp ( unsigned char *  buf,
time_t  fortime 
)
static

Definition at line 320 of file test_cimd2.c.

References gw_gmtime().

Referenced by gen_message(), handle_get(), and handle_submit().

320  {
321  /* Is there a thread-safe version of gmtime? */
322  struct tm tm = gw_gmtime(fortime);
323 
324  sprintf(buf, "%02d%02d%02d%02d%02d%02d",
325  tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
326  tm.tm_hour, tm.tm_min, tm.tm_sec);
327 }
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
static void parse_data ( Octstr in,
Octstr out 
)
static

Definition at line 817 of file test_cimd2.c.

References ETX, octstr_copy, octstr_delete(), octstr_destroy(), octstr_len(), octstr_search_char(), parse_packet(), and STX.

Referenced by main_loop().

817  {
818  int stx, etx;
819  Octstr *packet;
820 
821  for (;;) {
822  /* Look for start of packet. Delete everything up to the start
823  * marker. (CIMD2 section 3.1 says we can ignore any data
824  * transmitted between packets.) */
825  stx = octstr_search_char(in, STX, 0);
826  if (stx < 0)
827  octstr_delete(in, 0, octstr_len(in));
828  else if (stx > 0)
829  octstr_delete(in, 0, stx);
830 
831  etx = octstr_search_char(in, ETX, 0);
832  if (etx < 0)
833  return; /* Incomplete packet; wait for more data. */
834 
835  /* Copy the data between stx and etx */
836  packet = octstr_copy(in, 1, etx - 1);
837  /* Then cut the packet (including stx and etx) from inbuffer */
838  octstr_delete(in, 0, etx + 1);
839 
840  parse_packet(packet, out);
841 
842  octstr_destroy(packet);
843  }
844 }
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
static void parse_packet(Octstr *packet, Octstr *out)
Definition: test_cimd2.c:788
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static void parse_packet ( Octstr packet,
Octstr out 
)
static

Definition at line 788 of file test_cimd2.c.

References eat_char(), eat_checksum(), eat_number(), handlers, LOG_packets, logging, opcode, and send_error().

Referenced by parse_data().

788  {
789  int opcode, sequence;
790  int i;
791 
792  eat_checksum(packet);
793 
794  opcode = eat_number(packet);
795  if (opcode < 0 || eat_char(packet, ':') < 0)
796  return;
797  sequence = eat_number(packet);
798  if (sequence < 0)
799  return;
800 
801  for (i = 0; handlers[i].opcode >= 0; i++) {
802  if (handlers[i].opcode == opcode) {
803  (handlers[i].handler)(packet, out, sequence);
804  break;
805  }
806  }
807 
808  if (handlers[i].opcode < 0) { /* Loop failed */
809  if (logging == LOG_packets)
810  printf("RCV: unknown operation %ld\n",
811  (long) handlers[i].opcode);
812  send_error(out, 98, sequence, "1", "unexpected operation");
813  }
814 }
static long eat_number(Octstr *ostr)
Definition: test_cimd2.c:401
static int eat_char(Octstr *packet, int ch)
Definition: test_cimd2.c:368
static void eat_checksum(Octstr *packet)
Definition: test_cimd2.c:429
struct @77 handlers[]
static void send_error(Octstr *out, int opcode, int sequence, unsigned char *errorcode, unsigned char *errortext)
Definition: test_cimd2.c:360
int logging
Definition: test_cimd2.c:138
int opcode
Definition: test_cimd2.c:769
static void pretty_print ( unsigned char *  data,
size_t  length 
)
static

Definition at line 201 of file test_cimd2.c.

References CR, ETX, LF, STX, and TAB.

Referenced by read_data(), and write_data().

201  {
202  size_t i;
203  int c;
204 
205  for (i = 0; i < length; i++) {
206  c = data[i];
207  switch(c) {
208  default:
209  if (isprint(c))
210  putchar(c);
211  else
212  printf("<%d>", c);
213  break;
214  case TAB: fputs("<TAB>", stdout); break;
215  case LF: fputs("<LF>\n", stdout); break;
216  case CR: fputs("<CR>", stdout); break;
217  case STX: fputs("<STX>", stdout); break;
218  case ETX: fputs("<ETX>\n", stdout); break;
219  }
220  }
221  fflush(stdout);
222 }
Definition: test_cimd2.c:164
Definition: test_cimd2.c:163
static void random_address ( unsigned char *  buf,
int  size 
)
static

Definition at line 846 of file test_cimd2.c.

References size.

Referenced by gen_message().

846  {
847  int len = random() % size;
848 
849  while (len--) {
850  *buf++ = '0' + random() % 10;
851  }
852 
853  *buf++ = '\0';
854 }
int size
Definition: wsasm.c:84
static void random_hex ( unsigned char *  buf,
int  size 
)
static

Definition at line 869 of file test_cimd2.c.

References size.

Referenced by gen_message().

869  {
870  int len = random() % size;
871 
872  /* Make even */
873  len -= (len % 2);
874 
875  while (len--) {
876  int c = random() % 16;
877  if (c < 10)
878  *buf++ = c + '0';
879  else
880  *buf++ = c - 10 + 'a';
881  }
882 
883  *buf++ = '\0';
884 }
int size
Definition: wsasm.c:84
static void random_message ( unsigned char *  buf,
int  size 
)
static

Definition at line 856 of file test_cimd2.c.

References ETX, size, STX, and TAB.

Referenced by gen_message().

856  {
857  int len = random() % size;
858 
859  while (len--) {
860  do {
861  *buf = random() % 256;
862  } while (*buf == STX || *buf == ETX || *buf == TAB);
863  buf++;
864  }
865 
866  *buf++ = '\0';
867 }
int size
Definition: wsasm.c:84
static void read_data ( Octstr in,
int  fd 
)
static

Definition at line 224 of file test_cimd2.c.

References error(), EVIL_BUFSIZE, LOG_data, logging, octstr_append_data(), and pretty_print().

Referenced by main_loop().

224  {
225  unsigned char buf[EVIL_BUFSIZE];
226  int ret;
227 
228  ret = read(fd, buf, sizeof(buf));
229  if (ret > 0) {
230  octstr_append_data(in, buf, ret);
231  if (logging == LOG_data)
232  pretty_print(buf, ret);
233  } else if (ret == 0) {
234  fprintf(stderr, "Client closed socket\n");
235  exit(0);
236  } else {
237  if (errno == EINTR || errno == EAGAIN)
238  return;
239  error(errno, "read_data");
240  exit(1);
241  }
242 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1495
static void pretty_print(unsigned char *data, size_t length)
Definition: test_cimd2.c:201
int logging
Definition: test_cimd2.c:138
static void send_error ( Octstr out,
int  opcode,
int  sequence,
unsigned char *  errorcode,
unsigned char *  errortext 
)
static

Definition at line 360 of file test_cimd2.c.

References LOG_packets, logging, and send_packet().

Referenced by handle_cancel(), handle_delivery_request(), handle_enquire(), handle_get(), handle_login(), handle_set(), handle_submit(), and parse_packet().

361  {
362  if (logging == LOG_packets)
363  printf("SND: ERROR, %s\n", errortext);
364 
365  send_packet(out, opcode, sequence, 900, errorcode, 901, errortext, 0);
366 }
static void send_packet(Octstr *out, int opcode, int sequence,...)
Definition: test_cimd2.c:330
int logging
Definition: test_cimd2.c:138
int opcode
Definition: test_cimd2.c:769
static void send_packet ( Octstr out,
int  opcode,
int  sequence,
  ... 
)
static

Definition at line 330 of file test_cimd2.c.

References ACT_listen, activity, ETX, octstr_format_append(), octstr_get_char(), octstr_len(), STX, and TAB.

Referenced by gen_message(), handle_alive(), handle_cancel(), handle_delivery_request(), handle_enquire(), handle_get(), handle_login(), handle_logout(), handle_submit(), and send_error().

330  {
331  va_list ap;
332  int parm;
333  unsigned char *value;
334  int checksum;
335  int old_len, new_len;
336 
337  if (activity == ACT_listen)
338  return;
339 
340  old_len = octstr_len(out);
341 
342  octstr_format_append(out, "%c%02d:%03d%c", STX, opcode, sequence, TAB);
343 
344  va_start(ap, sequence);
345  for (parm = va_arg(ap, int); parm != 0; parm = va_arg(ap, int)) {
346  value = va_arg(ap, unsigned char *);
347  octstr_format_append(out, "%03d:%s\11", parm, value);
348  }
349  va_end(ap);
350 
351  /* Calculate checksum */
352  checksum = 0;
353  for (new_len = octstr_len(out); old_len < new_len; old_len++) {
354  checksum = (checksum + octstr_get_char(out, old_len)) & 0xff;
355  }
356 
357  octstr_format_append(out, "%02X%c", checksum, ETX);
358 }
Definition: seewbmp.c:154
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
int activity
Definition: test_cimd2.c:136
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
int opcode
Definition: test_cimd2.c:769
static void usage ( FILE *  out)
static

Definition at line 167 of file test_cimd2.c.

References activity, checking, logging, password, progname, spew, and username.

Referenced by main().

167  {
168  fprintf(out, "Usage: %s [options...]\n"
169 " --help Print this message\n"
170 " --user USER Allow clients to log in with username USER (default %s)\n"
171 " --password PASS Allow clients to log in with password PASS (default %s)\n"
172 " --intro INTRO Send INTRO string before anything else (default nothing)\n"
173 " --port PORT TCP port to listen on (default %d)\n"
174 " --activity ACT Activity level of test server (default %d)\n"
175 " ACT = 0 send nothing, just listen\n"
176 " ACT = 1 send valid replies, do not initiate any transactions\n"
177 " ACT = 2 attempt to deliver a random SMS every few seconds (NI)\n"
178 " ACT = 3 deliver many random SMSes, measure throughput (NI)\n"
179 " --spew SPEW Flood client, overrides --activity (default %d)\n"
180 " SPEW = 0 don't spew, use --activity instead\n"
181 " SPEW = 1 spew random binary gunk at client\n"
182 " SPEW = 2 spew random data of the right character set at client (NI)\n"
183 " SPEW = 3 spew valid packets with random contents at client (NI)\n"
184 " --logging LOG Log level of test server (default %d)\n"
185 " LOG = 0 log nothing\n"
186 " LOG = 1 log all data\n"
187 " LOG = 2 log summaries of valid packets\n"
188 " LOG = 3 log successfully sent and received SMSes (NI)\n"
189 " --checking CHK Check level of test server (default %d)\n"
190 " CHK = 0 check nothing\n"
191 " CHK = 1 signal invalid packets (NI)\n"
192 " CHK = 2 signal checksum errors (NI)\n"
193 " CHK = 3 signal protocol errors (NI)\n"
194 " CHK = 4 signal invalid SMS contents (NI)\n"
195 " --max MAX With high activity values, stop after MAX deliveries\n"
196 " NI means Not Implemented\n"
199 }
Definition: http.c:1998
unsigned char * username
Definition: test_cimd2.c:99
unsigned char * password
Definition: test_cimd2.c:100
int activity
Definition: test_cimd2.c:136
int logging
Definition: test_cimd2.c:138
int spew
Definition: test_cimd2.c:137
unsigned char * progname
Definition: test_cimd2.c:96
int checking
Definition: test_cimd2.c:139
static int wait_for_client ( int  port)
static

Definition at line 1016 of file test_cimd2.c.

References error(), gw_netaddr_to_octstr(), info(), make_server_socket(), octstr_destroy(), octstr_get_cstr, panic, progname, and socket_set_blocking().

Referenced by main().

1016  {
1017  struct sockaddr_in sin;
1018  socklen_t addrlen;
1019  int listenfd;
1020  int clientfd;
1021  Octstr *addr;
1022 
1023  listenfd = make_server_socket(port, NULL);
1024  if (listenfd < 0) {
1025  fprintf(stderr, "%s: failed to open socket at port %d\n",
1026  progname, port);
1027  exit(1);
1028  }
1029 
1030  do {
1031  addrlen = sizeof(sin);
1032  clientfd = accept(listenfd, (struct sockaddr *)&sin, &addrlen);
1033  if (clientfd < 0) {
1034  error(errno, "failed to accept new connection");
1035  }
1036  } while (clientfd < 0);
1037 
1038  if (socket_set_blocking(clientfd, 0) < 0) {
1039  panic(0, "failed to make client socket nonblocking");
1040  }
1041 
1042  addr = gw_netaddr_to_octstr(AF_INET, &sin.sin_addr);
1043  info(0, "Accepted client from %s:%d",
1044  octstr_get_cstr(addr), ntohs(sin.sin_port));
1045  octstr_destroy(addr);
1046 
1047  close(listenfd);
1048 
1049  return clientfd;
1050 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
int socket_set_blocking(int fd, int blocking)
Definition: socket.c:368
Definition: http.c:1998
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * gw_netaddr_to_octstr(int af, void *src)
Definition: socket.c:677
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
#define panic
Definition: log.h:87
int socklen_t
Definition: socket.h:73
unsigned char * progname
Definition: test_cimd2.c:96
static void write_data ( Octstr out,
int  fd 
)
static

Definition at line 244 of file test_cimd2.c.

References error(), EVIL_BUFSIZE, LOG_data, logging, octstr_delete(), octstr_get_many_chars(), octstr_len(), pretty_print(), and warning().

Referenced by main_loop().

244  {
245  unsigned char buf[EVIL_BUFSIZE];
246  int len;
247  ssize_t ret;
248 
249  len = sizeof(buf);
250  if (len > octstr_len(out))
251  len = octstr_len(out);
252  if (len == 0)
253  return;
254  octstr_get_many_chars(buf, out, 0, len);
255  ret = write(fd, buf, len);
256  if (ret > 0) {
257  if (logging == LOG_data)
258  pretty_print(buf, ret);
259  octstr_delete(out, 0, ret);
260  } else if (ret == 0) {
261  warning(0, "empty write");
262  } else {
263  if (errno == EINTR || errno == EAGAIN)
264  return;
265  error(errno, "write_data");
266  exit(1);
267  }
268 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
void warning(int err, const char *fmt,...)
Definition: log.c:624
static void pretty_print(unsigned char *data, size_t length)
Definition: test_cimd2.c:201
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
int logging
Definition: test_cimd2.c:138
void octstr_get_many_chars(char *buf, Octstr *ostr, long pos, long len)
Definition: octstr.c:423

Variable Documentation

int activity = ACT_listen

Definition at line 136 of file test_cimd2.c.

Referenced by gen_data(), send_packet(), and usage().

int checking = CHK_nothing

Definition at line 139 of file test_cimd2.c.

Referenced by usage().

int deliveries = 0

Definition at line 142 of file test_cimd2.c.

Referenced by gen_data(), and handle_deliver_response().

packet_handler handler

Definition at line 770 of file test_cimd2.c.

struct { ... } handlers[]
Initial value:
= {
{ 1, handle_login },
{ 2, handle_logout },
{ 3, handle_submit },
{ 6, handle_cancel },
{ 8, handle_set },
{ 9, handle_get },
{ 40, handle_alive },
{ 99, handle_nack },
{ -1, NULL },
}
static void handle_deliver_status_report_response(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:744
static void handle_delivery_request(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:614
static void handle_submit(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:480
static void handle_logout(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:472
static void handle_nack(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:758
static void handle_login(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:446
static void handle_alive(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:723
static void handle_set(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:685
static void handle_alive_response(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:751
static void handle_get(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:702
static void handle_deliver_response(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:731
static void handle_cancel(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:659
static void handle_enquire(Octstr *packet, Octstr *out, int sequence)
Definition: test_cimd2.c:588

Referenced by parse_packet().

Octstr* inbuffer

Definition at line 147 of file test_cimd2.c.

unsigned char* intro = ""

Definition at line 105 of file test_cimd2.c.

Referenced by main_loop().

void* location

Definition at line 1001 of file test_cimd2.c.

Referenced by at2_read_pending_incoming_messages().

int max_deliveries = -1

Definition at line 141 of file test_cimd2.c.

Referenced by gen_data(), and handle_deliver_response().

int number

Definition at line 1002 of file test_cimd2.c.

Referenced by handle_get(), and main().

int opcode

Definition at line 769 of file test_cimd2.c.

Referenced by parse_packet().

unsigned char* option

Definition at line 1000 of file test_cimd2.c.

Referenced by main(), and parse_options().

struct { ... } options[]
Initial value:
= {
{ "--user", &username, 0 },
{ "--password", &password, 0 },
{ "--port", &port, 1 },
{ "--intro", &intro, 0 },
{ "--activity", &activity, 1 },
{ "--spew", &spew, 1 },
{ "--logging", &logging, 1 },
{ "--checking", &checking, 1 },
{ "--max", &max_deliveries, 1 },
{ NULL, NULL, 0 },
}
int port
Definition: test_cimd2.c:102
unsigned char * username
Definition: test_cimd2.c:99
unsigned char * password
Definition: test_cimd2.c:100
unsigned char * intro
Definition: test_cimd2.c:105
int activity
Definition: test_cimd2.c:136
int max_deliveries
Definition: test_cimd2.c:141
int logging
Definition: test_cimd2.c:138
int spew
Definition: test_cimd2.c:137
int checking
Definition: test_cimd2.c:139

Referenced by main().

Octstr* outbuffer

Definition at line 148 of file test_cimd2.c.

int port = 6789

Definition at line 102 of file test_cimd2.c.

unsigned char* progname

Definition at line 96 of file test_cimd2.c.

Referenced by main(), usage(), and wait_for_client().

int sockfd = -1

Definition at line 145 of file test_cimd2.c.

Referenced by conn_open_tcp_nb_with_port(), conn_open_tcp_with_port(), main(), and main_loop().

int spew = SPEW_nothing

Definition at line 137 of file test_cimd2.c.

Referenced by gen_data(), and usage().

time_t start_time = 0

Definition at line 143 of file test_cimd2.c.

Referenced by handle_deliver_response(), and main_loop().

unsigned char* username = "foo"
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.