1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  *
16  *  Author : Richard GAYRAUD - 04 Nov 2003
17  *           Olivier Jacques
18  *           From Hewlett Packard Company.
19  *           Shriram Natarajan
20  *           Peter Higginson
21  *           Venkatesh
22  *           Lee Ballard
23  *           Guillaume TEISSIER from FTR&D
24  *           Wolfgang Beck
25  *           Marc Van Diest from Belgacom
26  *           Charles P. Wright from IBM Research
27  *           Michael Stovenour
28  */
29 
30 #include <stdlib.h>
31 #include "sipp.hpp"
32 #ifdef HAVE_GSL
33 #include <gsl/gsl_rng.h>
34 #include <gsl/gsl_randist.h>
35 #include <gsl/gsl_cdf.h>
36 #endif
37 
38 /************************ Class Constructor *************************/
39 
message(int index,const char * desc)40 message::message(int index, const char *desc)
41 {
42     this->index = index;
43     this->desc = desc;
44     pause_distribution = NULL; // delete on exit
45     pause_variable = -1;
46     pause_desc = NULL; // free on exit
47     sessions = 0;
48     bShouldRecordRoutes = 0;
49     bShouldAuthenticate = 0;
50 
51     send_scheme = NULL; // delete on exit
52     retrans_delay = 0;
53     timeout = 0;
54 
55     recv_response = 0;
56     recv_request = NULL; // free on exit
57     optional = 0;
58     advance_state = true;
59     regexp_match = 0;
60     regexp_compile = NULL; // regfree (if not NULL) and free on exit
61 
62     /* Anyway */
63     start_rtd = 0;
64     stop_rtd  = 0;
65     repeat_rtd = 0;
66     lost = -1;
67     crlf = 0;
68     hide = 0;
69     display_str = NULL; // free on exit
70     test = -1;
71     condexec = -1;
72     condexec_inverse = false;
73     chance = 0;/* meaning always */
74     next = -1;
75     nextLabel = NULL; // free on exit
76     on_timeout = -1;
77     onTimeoutLabel = NULL; // free on exit
78     timewait = false;
79 
80     /* 3pcc extended mode */
81     peer_dest = NULL; // free on exit
82     peer_src = NULL; // free on exit
83 
84     /* Statistics */
85     nb_sent = 0;
86     nb_recv = 0;
87     nb_sent_retrans = 0;
88     nb_recv_retrans = 0;
89     nb_timeout = 0;
90     nb_unexp = 0;
91     nb_lost = 0;
92     counter = 0;
93 
94     M_actions = NULL; // delete on exit
95 
96     M_type = 0;
97 
98     M_sendCmdData = NULL; // delete on exit
99     M_nbCmdSent   = 0;
100     M_nbCmdRecv   = 0;
101 
102     content_length_flag = ContentLengthNoPresent;
103 
104     /* How to match responses to this message. */
105     start_txn = 0;
106     response_txn = 0;
107     ack_txn = 0;
108     recv_response_for_cseq_method_list = NULL; // free on exit
109 }
110 
~message()111 message::~message()
112 {
113   delete(pause_distribution);
114   free(pause_desc);
115   delete(send_scheme);
116   free(recv_request);
117   if (regexp_compile != NULL) {
118     regfree(regexp_compile);
119   }
120   free(regexp_compile);
121 
122   free(display_str);
123   free(nextLabel);
124   free(onTimeoutLabel);
125 
126   free(peer_dest);
127   free(peer_src);
128 
129   delete(M_actions);
130   delete(M_sendCmdData);
131   free(recv_response_for_cseq_method_list);
132 }
133 
134 /******** Global variables which compose the scenario file **********/
135 
136 scenario      *main_scenario;
137 scenario      *ooc_scenario;
138 scenario      *aa_scenario;
139 scenario      *display_scenario;
140 
141 /* This mode setting refers to whether we open calls autonomously (MODE_CLIENT)
142  * or in response to requests (MODE_SERVER). */
143 int creationMode  = MODE_CLIENT;
144 /* Send mode. Do we send to a fixed address or to the last one we got. */
145 int sendMode  = MODE_CLIENT;
146 /* This describes what our 3PCC behavior is. */
147 int thirdPartyMode = MODE_3PCC_NONE;
148 
149 /*************** Helper functions for various types *****************/
get_long(const char * ptr,const char * what)150 long get_long(const char *ptr, const char *what)
151 {
152     char *endptr;
153     long ret;
154 
155     ret = strtol(ptr, &endptr, 0);
156     if (*endptr) {
157         ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
158     }
159     return ret;
160 }
161 
get_long_long(const char * ptr,const char * what)162 unsigned long long get_long_long(const char *ptr, const char *what)
163 {
164     char *endptr;
165     unsigned long long ret;
166 
167     ret = strtoull(ptr, &endptr, 0);
168     if (*endptr) {
169         ERROR("%s, \"%s\" is not a valid integer!\n", what, ptr);
170     }
171     return ret;
172 }
173 
174 /* This function returns a time in milliseconds from a string.
175  * The multiplier is used to convert from the default input type into
176  * milliseconds.  For example, for seconds you should use 1000 and for
177  * milliseconds use 1. */
get_time(const char * ptr,const char * what,int multiplier)178 long get_time(const char *ptr, const char *what, int multiplier)
179 {
180     char *endptr;
181     const char *p;
182     long ret;
183     double dret;
184     int i;
185 
186     if (!isdigit(*ptr)) {
187         ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
188     }
189 
190     for (i = 0, p = ptr; *p; p++) {
191         if (*p == ':') {
192             i++;
193         }
194     }
195 
196     if (i == 1) { /* mm:ss */
197         ERROR("%s, \"%s\" mm:ss not implemented yet!\n", what, ptr);
198     } else if (i == 2) { /* hh:mm:ss */
199         ERROR("%s, \"%s\" hh:mm:ss not implemented yet!\n", what, ptr);
200     } else if (i != 0) {
201         ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
202     }
203 
204     dret = strtod(ptr, &endptr);
205     if (*endptr) {
206         if (!strcmp(endptr, "s")) { /* Seconds */
207             ret = (long)(dret * 1000);
208         } else if (!strcmp(endptr, "ms")) { /* Milliseconds. */
209             ret = (long)dret;
210         } else if (!strcmp(endptr, "m")) { /* Minutes. */
211             ret = (long)(dret * 60000);
212         } else if (!strcmp(endptr, "h")) { /* Hours. */
213             ret = (long)(dret * 60 * 60 * 1000);
214         } else {
215             ERROR("%s, \"%s\" is not a valid time!\n", what, ptr);
216         }
217     } else {
218         ret = (long)(dret * multiplier);
219     }
220     return ret;
221 }
222 
get_double(const char * ptr,const char * what)223 double get_double(const char *ptr, const char *what)
224 {
225     char *endptr;
226     double ret;
227 
228     ret = strtod(ptr, &endptr);
229     if (*endptr) {
230         ERROR("%s, \"%s\" is not a floating point number!\n", what, ptr);
231     }
232     return ret;
233 }
234 
235 #ifdef PCAPPLAY
236 /* Return static buffer to xml value, as with xp_get_value().
237  * If the value is enclosed in [brackets], it is assumed to be
238  * a command-line supplied keyword value (-key). */
xp_get_keyword_value(const char * name)239 static const char* xp_get_keyword_value(const char *name)
240 {
241     const char* ptr = xp_get_value(name);
242     size_t len;
243 
244     if (ptr && ptr[0] == '[' && (len = strlen(ptr)) && ptr[len - 1] == ']') {
245         int i = 0;
246         len -= 2; /* without the brackets */
247         while (generic[i]) {
248             const char* keyword = *generic[i];
249             if (strncmp(ptr + 1, keyword, len) == 0 && strlen(keyword) == len) {
250                 const char* value = *(generic[i] + 1);
251                 return strdup(value);
252             }
253             ++i;
254         }
255         ERROR("%s \"%s\" looks like a keyword value, but keyword not supplied!\n", name, ptr);
256     }
257 
258     return ptr;
259 }
260 #endif
261 
xp_get_string(const char * name,const char * what)262 static char* xp_get_string(const char *name, const char *what)
263 {
264     char *ptr;
265 
266     if (!(ptr = xp_get_value(name))) {
267         ERROR("%s is missing the required '%s' parameter.", what, name);
268     }
269 
270     return strdup(ptr);
271 }
272 
xp_get_double(const char * name,const char * what)273 static double xp_get_double(const char *name, const char *what)
274 {
275     char *ptr;
276     char *helptext;
277     double val;
278 
279     if (!(ptr = xp_get_value(name))) {
280         ERROR("%s is missing the required '%s' parameter.", what, name);
281     }
282     helptext = (char *)malloc(100 + strlen(name) + strlen(what));
283     sprintf(helptext, "%s '%s' parameter", what, name);
284     val = get_double(ptr, helptext);
285     free(helptext);
286 
287     return val;
288 }
289 
xp_get_long(const char * name,const char * what)290 static long xp_get_long(const char *name, const char *what)
291 {
292     char *ptr;
293     char *helptext;
294     long val;
295 
296     if (!(ptr = xp_get_value(name))) {
297         ERROR("%s is missing the required '%s' parameter.", what, name);
298     }
299     helptext = (char *)malloc(100 + strlen(name) + strlen(what));
300     sprintf(helptext, "%s '%s' parameter", what, name);
301     val = get_long(ptr, helptext);
302     free(helptext);
303 
304     return val;
305 }
306 
xp_get_long(const char * name,const char * what,long defval)307 static long xp_get_long(const char *name, const char *what, long defval)
308 {
309     if (!(xp_get_value(name))) {
310         return defval;
311     }
312     return xp_get_long(name, what);
313 }
314 
315 
xp_get_bool(const char * name,const char * what)316 static bool xp_get_bool(const char *name, const char *what)
317 {
318     char *ptr;
319     char *helptext;
320     bool val;
321 
322     if (!(ptr = xp_get_value(name))) {
323         ERROR("%s is missing the required '%s' parameter.", what, name);
324     }
325     helptext = (char *)malloc(100 + strlen(name) + strlen(what));
326     sprintf(helptext, "%s '%s' parameter", what, name);
327     val = get_bool(ptr, helptext);
328     free(helptext);
329 
330     return val;
331 }
332 
xp_get_bool(const char * name,const char * what,bool defval)333 static bool xp_get_bool(const char *name, const char *what, bool defval)
334 {
335     if (!(xp_get_value(name))) {
336         return defval;
337     }
338     return xp_get_bool(name, what);
339 }
340 
get_txn(const char * txnName,const char * what,bool start,bool isInvite,bool isAck)341 int scenario::get_txn(const char *txnName, const char *what, bool start, bool isInvite, bool isAck)
342 {
343     /* Check the name's validity. */
344     if (txnName[0] == '\0') {
345         ERROR("Variable names may not be empty for %s\n", what);
346     }
347     if (strcspn(txnName, "$,") != strlen(txnName)) {
348         ERROR("Variable names may not contain $ or , for %s\n", what);
349     }
350 
351     /* If this transaction has already been used, then we have nothing to do. */
352     str_int_map::iterator txn_it = txnMap.find(txnName);
353     if (txn_it != txnMap.end()) {
354         if (start) {
355             /* We need to fill in the invite field. */
356             transactions[txn_it->second - 1].started++;
357         } else if (isAck) {
358             transactions[txn_it->second - 1].acks++;
359         } else {
360             transactions[txn_it->second - 1].responses++;
361         }
362         return txn_it->second;
363     }
364 
365     /* Assign this variable the next slot. */
366     struct txnControlInfo transaction;
367 
368     transaction.name = strdup(txnName);
369     if (start) {
370         transaction.started = 1;
371         transaction.responses = 0;
372         transaction.acks = 0;
373         transaction.isInvite = isInvite;
374     } else if (isAck) {
375         /* Does not start or respond to this txn. */
376         transaction.started = 0;
377         transaction.responses = 0;
378         transaction.acks = 1;
379         transaction.isInvite = false;
380     } else {
381         transaction.started = 0;
382         transaction.responses = 1;
383         transaction.acks = 0;
384         transaction.isInvite = false;
385     }
386 
387     transactions.push_back(transaction);
388     int txnNum = transactions.size();
389     txnMap[txnName] = txnNum;
390 
391     return txnNum;
392 }
393 
find_var(const char * varName)394 int scenario::find_var(const char *varName)
395 {
396     return allocVars->find(varName, false);
397 }
398 
get_var(const char * varName,const char * what)399 int scenario::get_var(const char *varName, const char *what)
400 {
401     /* Check the name's validity. */
402     if (varName[0] == '\0') {
403         ERROR("Transaction names may not be empty for %s\n", what);
404     }
405     if (strcspn(varName, "$,") != strlen(varName)) {
406         ERROR("Transaction names may not contain $ or , for %s\n", what);
407     }
408 
409     return allocVars->find(varName, true);
410 }
411 
xp_get_var(const char * name,const char * what)412 int scenario::xp_get_var(const char *name, const char *what)
413 {
414     char *ptr;
415 
416     if (!(ptr = xp_get_value(name))) {
417         ERROR("%s is missing the required '%s' variable parameter.", what, name);
418     }
419 
420     return get_var(ptr, what);
421 }
422 
xp_get_optional(const char * name,const char * what)423 static int xp_get_optional(const char *name, const char *what)
424 {
425     char *ptr = xp_get_value(name);
426 
427     if (!ptr) {
428         return OPTIONAL_FALSE;
429     }
430 
431     if(!strcmp(ptr, "true")) {
432         return OPTIONAL_TRUE;
433     } else if(!strcmp(ptr, "global")) {
434         return OPTIONAL_GLOBAL;
435     } else if(!strcmp(ptr, "false")) {
436         return OPTIONAL_FALSE;
437     } else {
438         ERROR("Could not understand optional value for %s: %s", what, ptr);
439     }
440 
441     return OPTIONAL_FALSE;
442 }
443 
444 
xp_get_var(const char * name,const char * what,int defval)445 int scenario::xp_get_var(const char *name, const char *what, int defval)
446 {
447     char *ptr;
448 
449     if (!(ptr = xp_get_value(name))) {
450         return defval;
451     }
452 
453     return xp_get_var(name, what);
454 }
455 
get_bool(const char * ptr,const char * what)456 bool get_bool(const char *ptr, const char *what)
457 {
458     char *endptr;
459     long ret;
460 
461     if (!strcasecmp(ptr, "true")) {
462         return true;
463     }
464     if (!strcasecmp(ptr, "false")) {
465         return false;
466     }
467 
468     ret = strtol(ptr, &endptr, 0);
469     if (*endptr) {
470         ERROR("%s, \"%s\" is not a valid boolean!\n", what, ptr);
471     }
472     return ret ? true : false;
473 }
474 
475 /* Pretty print a time. */
time_string(double ms,char * res,int reslen)476 int time_string(double ms, char *res, int reslen)
477 {
478     if (ms < 10000) {
479         /* Less then 10 seconds we represent accurately. */
480         if ((int)(ms + 0.9999) == (int)(ms)) {
481             /* We have an integer, or close enough to it. */
482             return snprintf(res, reslen, "%dms", (int)ms);
483         } else {
484             if (ms < 1000) {
485                 return snprintf(res, reslen, "%.2lfms", ms);
486             } else {
487                 return snprintf(res, reslen, "%.1lfms", ms);
488             }
489         }
490     } else if (ms < 60000) {
491         /* We round to 100ms for times less than a minute. */
492         return snprintf(res, reslen, "%.1fs", ms/1000);
493     } else if (ms < 60 * 60000) {
494         /* We round to 1s for times more than a minute. */
495         int s = (unsigned int)(ms / 1000);
496         int m = s / 60;
497         s %= 60;
498         return snprintf(res, reslen, "%d:%02d", m, s);
499     } else {
500         int s = (unsigned int)(ms / 1000);
501         int m = s / 60;
502         int h = m / 60;
503         s %= 60;
504         m %= 60;
505         return snprintf(res, reslen, "%d:%02d:%02d", h, m, s);
506     }
507 }
508 
509 /* For backwards compatibility, we assign "true" to slot 1, false to 0, and
510  * allow other valid integers. */
get_rtd(const char * ptr,bool start)511 int scenario::get_rtd(const char *ptr, bool start)
512 {
513     if(!strcmp(ptr, (char *)"false"))
514         return 0;
515 
516     if(!strcmp(ptr, (char *)"true"))
517         return stats->findRtd("1", start);
518 
519     return stats->findRtd(ptr, start);
520 }
521 
522 /* Get a counter */
get_counter(const char * ptr,const char * what)523 int scenario::get_counter(const char *ptr, const char *what)
524 {
525     /* Check the name's validity. */
526     if (ptr[0] == '\0') {
527         ERROR("Counter names names may not be empty for %s\n", what);
528     }
529     if (strcspn(ptr, "$,") != strlen(ptr)) {
530         ERROR("Counter names may not contain $ or , for %s\n", what);
531     }
532 
533     return stats->findCounter(ptr, true);
534 }
535 
536 
537 /* Some validation functions. */
538 
validate_variable_usage()539 void scenario::validate_variable_usage()
540 {
541     allocVars->validate();
542 }
543 
validate_txn_usage()544 void scenario::validate_txn_usage()
545 {
546     for (unsigned int i = 0; i < transactions.size(); i++) {
547         if(transactions[i].started == 0) {
548             ERROR("Transaction %s is never started!\n", transactions[i].name);
549         } else if(transactions[i].responses == 0) {
550             ERROR("Transaction %s has no responses defined!\n", transactions[i].name);
551         }
552         if (transactions[i].isInvite && transactions[i].acks == 0) {
553             ERROR("Transaction %s is an INVITE transaction without an ACK!\n", transactions[i].name);
554         }
555         if (!transactions[i].isInvite && (transactions[i].acks > 0)) {
556             ERROR("Transaction %s is a non-INVITE transaction with an ACK!\n", transactions[i].name);
557         }
558     }
559 }
560 
561 /* Apply the next and ontimeout labels according to our map. */
apply_labels(msgvec v,str_int_map labels)562 void scenario::apply_labels(msgvec v, str_int_map labels)
563 {
564     for (unsigned int i = 0; i < v.size(); i++) {
565         if (v[i]->nextLabel) {
566             str_int_map::iterator label_it = labels.find(v[i]->nextLabel);
567             if (label_it == labels.end()) {
568                 ERROR("The label '%s' was not defined (index %d, next attribute)\n", v[i]->nextLabel, i);
569             }
570             v[i]->next = label_it->second;
571         }
572         if (v[i]->onTimeoutLabel) {
573             str_int_map::iterator label_it = labels.find(v[i]->onTimeoutLabel);
574             if (label_it == labels.end()) {
575                 ERROR("The label '%s' was not defined (index %d, ontimeout attribute)\n", v[i]->onTimeoutLabel, i);
576             }
577             v[i]->on_timeout = label_it->second;
578         }
579     }
580 }
581 
get_cr_number(const char * src)582 int get_cr_number(const char *src)
583 {
584     int res=0;
585     while(*src) {
586         if(*src == '\n') res++;
587         src++;
588     }
589     return res;
590 }
591 
clean_cdata(char * ptr,int * removed_crlf=NULL)592 static char* clean_cdata(char *ptr, int *removed_crlf = NULL)
593 {
594     char * msg;
595 
596     while((*ptr == ' ') || (*ptr == '\t') || (*ptr == '\n')) ptr++;
597 
598     msg = (char *) malloc(strlen(ptr) + 3);
599     if(!msg) {
600         ERROR("Memory Overflow");
601     }
602     strcpy(msg, ptr);
603 
604     ptr = msg + strlen(msg);
605     ptr --;
606 
607     while((ptr >= msg) &&
608             ((*ptr == ' ')  ||
609              (*ptr == '\t') ||
610              (*ptr == '\n'))) {
611         if(*ptr == '\n' && removed_crlf) {
612             (*removed_crlf)++;
613         }
614         *ptr-- = 0;
615     }
616 
617     if(!strstr(msg, "\n\n")) {
618         strcat(msg, "\n\n");
619     }
620 
621     if(ptr == msg) {
622         ERROR("Empty cdata in xml scenario file");
623     }
624     while ((ptr = strstr(msg, "\n "))) {
625         memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
626     }
627     while ((ptr = strstr(msg, " \n"))) {
628         memmove(ptr, ptr + 1, strlen(ptr));
629     }
630     while ((ptr = strstr(msg, "\n\t"))) {
631         memmove(ptr + 1, ptr + 2, strlen(ptr) - 1);
632     }
633     while ((ptr = strstr(msg, "\t\n"))) {
634         memmove(ptr, ptr + 1, strlen(ptr));
635     }
636 
637     return msg;
638 }
639 
640 
641 
642 /********************** Scenario File analyser **********************/
643 
checkOptionalRecv(char * elem,unsigned int scenario_file_cursor)644 void scenario::checkOptionalRecv(char *elem, unsigned int scenario_file_cursor)
645 {
646     if (last_recv_optional) {
647         ERROR("<recv> before <%s> sequence without a mandatory message. Please remove one 'optional=true' (element %d).", elem, scenario_file_cursor);
648     }
649     last_recv_optional = false;
650 }
651 
scenario(char * filename,int deflt)652 scenario::scenario(char * filename, int deflt)
653 {
654     char * elem;
655     char *method_list = NULL;
656     unsigned int scenario_file_cursor = 0;
657     int    L_content_length = 0 ;
658     char * peer;
659     const char* cptr;
660 
661     last_recv_optional = false;
662 
663     if(filename) {
664         if(!xp_set_xml_buffer_from_file(filename)) {
665             ERROR("Unable to load or parse '%s' xml scenario file", filename);
666         }
667     } else {
668         if(!xp_set_xml_buffer_from_string(default_scenario[deflt])) {
669             ERROR("Unable to load default xml scenario file");
670         }
671     }
672 
673     stats = new CStat();
674     allocVars = new AllocVariableTable(userVariables);
675 
676     hidedefault = false;
677 
678     elem = xp_open_element(0);
679     if (!elem) {
680         ERROR("No element in xml scenario file");
681     }
682     if(strcmp("scenario", elem)) {
683         ERROR("No 'scenario' section in xml scenario file");
684     }
685 
686     if ((cptr = xp_get_value("name"))) {
687         name = strdup(cptr);
688     } else {
689         name = strdup("");
690     }
691 
692     duration = 0;
693     found_timewait = false;
694 
695     scenario_file_cursor = 0;
696 
697     while ((elem = xp_open_element(scenario_file_cursor))) {
698         char * ptr;
699         scenario_file_cursor ++;
700 
701         if(!strcmp(elem, "CallLengthRepartition")) {
702             ptr = xp_get_string("value", "CallLengthRepartition");
703             stats->setRepartitionCallLength(ptr);
704             free(ptr);
705         } else if(!strcmp(elem, "ResponseTimeRepartition")) {
706             ptr = xp_get_string("value", "ResponseTimeRepartition");
707             stats->setRepartitionResponseTime(ptr);
708             free(ptr);
709         } else if(!strcmp(elem, "Global")) {
710             ptr = xp_get_string("variables", "Global");
711 
712             char **       currentTabVarName = NULL;
713             int           currentNbVarNames;
714 
715             createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
716             for (int i = 0; i < currentNbVarNames; i++) {
717                 globalVariables->find(currentTabVarName[i], true);
718             }
719             freeStringTable(currentTabVarName, currentNbVarNames);
720             free(ptr);
721         } else if(!strcmp(elem, "User")) {
722             ptr = xp_get_string("variables", "User");
723 
724             char **       currentTabVarName = NULL;
725             int           currentNbVarNames;
726 
727             createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
728             for (int i = 0; i < currentNbVarNames; i++) {
729                 userVariables->find(currentTabVarName[i], true);
730             }
731             freeStringTable(currentTabVarName, currentNbVarNames);
732             free(ptr);
733         } else if(!strcmp(elem, "Reference")) {
734             ptr = xp_get_string("variables", "Reference");
735 
736             char **       currentTabVarName = NULL;
737             int           currentNbVarNames;
738 
739             createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
740             for (int i = 0; i < currentNbVarNames; i++) {
741                 int id = allocVars->find(currentTabVarName[i], false);
742                 if (id == -1) {
743                     ERROR("Could not reference non-existant variable '%s'", currentTabVarName[i]);
744                 }
745             }
746             freeStringTable(currentTabVarName, currentNbVarNames);
747             free(ptr);
748         } else if(!strcmp(elem, "DefaultMessage")) {
749             char *id = xp_get_string("id", "DefaultMessage");
750             if(!(ptr = xp_get_cdata())) {
751                 ERROR("No CDATA in 'send' section of xml scenario file");
752             }
753             char *msg = clean_cdata(ptr);
754             set_default_message(id, msg);
755             free(id);
756             /* XXX: This should really be per scenario. */
757         } else if(!strcmp(elem, "label")) {
758             ptr = xp_get_string("id", "label");
759             if (labelMap.find(ptr) != labelMap.end()) {
760                 ERROR("The label name '%s' is used twice.", ptr);
761             }
762             labelMap[ptr] = messages.size();
763             free(ptr);
764         } else if (!strcmp(elem, "init")) {
765             /* We have an init section, which must be full of nops or labels. */
766             int nop_cursor = 0;
767             char *initelem;
768             while ((initelem = xp_open_element(nop_cursor++))) {
769                 if (!strcmp(initelem, "nop")) {
770                     /* We should parse this. */
771                     message *nopmsg = new message(initmessages.size(), "scenario initialization");
772                     initmessages.push_back(nopmsg);
773                     nopmsg->M_type = MSG_TYPE_NOP;
774                     getCommonAttributes(nopmsg);
775                 } else if (!strcmp(initelem, "label")) {
776                     /* Add an init label. */
777                     cptr = xp_get_value("id");
778                     if (initLabelMap.find(cptr) != initLabelMap.end()) {
779                         ERROR("The label name '%s' is used twice.", cptr);
780                     }
781                     initLabelMap[cptr] = initmessages.size();
782                 } else {
783                     ERROR("Invalid element in an init stanza: '%s'", initelem);
784                 }
785                 xp_close_element();
786             }
787         } else { /** Message Case */
788             if (found_timewait) {
789                 ERROR("<timewait> can only be the last message in a scenario!\n");
790             }
791             message *curmsg = new message(messages.size(), name ? name : "unknown scenario");
792             messages.push_back(curmsg);
793 
794             if(!strcmp(elem, "send")) {
795                 checkOptionalRecv(elem, scenario_file_cursor);
796                 curmsg->M_type = MSG_TYPE_SEND;
797                 /* Sent messages descriptions */
798                 if(!(ptr = xp_get_cdata())) {
799                     ERROR("No CDATA in 'send' section of xml scenario file");
800                 }
801 
802                 int removed_clrf = 0;
803                 char * msg = clean_cdata(ptr, &removed_clrf);
804 
805                 L_content_length = xp_get_content_length(msg);
806                 switch (L_content_length) {
807                 case  -1 :
808                     // the msg does not contain content-length field
809                     break ;
810                 case  0 :
811                     curmsg -> content_length_flag =
812                         message::ContentLengthValueZero;   // Initialize to No present
813                     break ;
814                 default :
815                     curmsg -> content_length_flag =
816                         message::ContentLengthValueNoZero;   // Initialize to No present
817                     break ;
818                 }
819 
820                 if((msg[strlen(msg) - 1] != '\n') && (removed_clrf)) {
821                     strcat(msg, "\n");
822                 }
823                 char *tsrc = msg;
824                 while(*tsrc++);
825                 curmsg -> send_scheme = new SendingMessage(this, msg);
826                 free(msg);
827 
828                 // If this is a request we are sending, then store our transaction/method matching information.
829                 if (!curmsg->send_scheme->isResponse()) {
830                     char *method = curmsg->send_scheme->getMethod();
831                     bool isInvite = !strcmp(method, "INVITE");
832                     bool isAck = !strcmp(method, "ACK");
833 
834                     if ((cptr = xp_get_value("start_txn"))) {
835                         if (isAck) {
836                             ERROR("An ACK message can not start a transaction!");
837                         }
838                         curmsg->start_txn = get_txn(cptr, "start transaction", true, isInvite, false);
839                     } else if ((cptr = xp_get_value("ack_txn"))) {
840                         if (!isAck) {
841                             ERROR("The ack_txn attribute is valid only for ACK messages!");
842                         }
843                         curmsg->ack_txn = get_txn(cptr, "ack transaction", false, false, true);
844                     } else {
845                         int len = method_list ? strlen(method_list) : 0;
846                         method_list = (char *)realloc(method_list, len + strlen(method) + 1);
847                         if (!method_list) {
848                             ERROR_NO("Out of memory allocating method_list!");
849                         }
850                         strcpy(method_list + len, method);
851                     }
852                 } else {
853                     if (xp_get_value("start_txn")) {
854                         ERROR("Responses can not start a transaction");
855                     }
856                     if (xp_get_value("ack_txn")) {
857                         ERROR("Responses can not ACK a transaction");
858                     }
859                 }
860 
861                 if (xp_get_value("response_txn")) {
862                     ERROR("response_txn can only be used for received messages.");
863                 }
864 
865                 curmsg -> retrans_delay = xp_get_long("retrans", "retransmission timer", 0);
866                 curmsg -> timeout = xp_get_long("timeout", "message send timeout", 0);
867             } else if (!strcmp(elem, "recv")) {
868                 curmsg->M_type = MSG_TYPE_RECV;
869                 /* Received messages descriptions */
870                 if((cptr = xp_get_value("response"))) {
871                     curmsg ->recv_response = get_long(cptr, "response code");
872                     if (method_list) {
873                         curmsg->recv_response_for_cseq_method_list = strdup(method_list);
874                     }
875                     if ((cptr = xp_get_value("response_txn"))) {
876                         curmsg->response_txn = get_txn(cptr, "transaction response", false, false, false);
877                     }
878                 }
879 
880                 if ((cptr = xp_get_value("request"))) {
881                     curmsg->recv_request = strdup(cptr);
882                     if (xp_get_value("response_txn")) {
883                         ERROR("response_txn can only be used for received responses.");
884                     }
885                 }
886 
887                 curmsg->optional = xp_get_optional("optional", "recv");
888                 last_recv_optional = curmsg->optional;
889                 curmsg->advance_state = xp_get_bool("advance_state", "recv", true);
890                 if (!curmsg->advance_state && curmsg->optional == OPTIONAL_FALSE) {
891                     ERROR("advance_state is allowed only for optional messages (index = %zu)\n", messages.size() - 1);
892                 }
893 
894                 if ((cptr = xp_get_value("regexp_match"))) {
895                     if (!strcmp(cptr, "true")) {
896                         curmsg->regexp_match = 1;
897                     }
898                 }
899 
900                 curmsg->timeout = xp_get_long("timeout", "message timeout", 0);
901 
902                 /* record the route set  */
903                 /* TODO disallow optional and rrs to coexist? */
904                 if ((cptr = xp_get_value("rrs"))) {
905                     curmsg->bShouldRecordRoutes = get_bool(cptr, "record route set");
906                 }
907 
908                 /* record the authentication credentials  */
909                 if ((cptr = xp_get_value("auth"))) {
910                     bool temp = get_bool(cptr, "message authentication");
911                     curmsg->bShouldAuthenticate = temp;
912                 }
913             } else if(!strcmp(elem, "pause") || !strcmp(elem, "timewait")) {
914                 checkOptionalRecv(elem, scenario_file_cursor);
915                 curmsg->M_type = MSG_TYPE_PAUSE;
916                 if (!strcmp(elem, "timewait")) {
917                     curmsg->timewait = true;
918                     found_timewait = true;
919                 }
920 
921                 int var;
922                 if ((var = xp_get_var("variable", "pause", -1)) != -1) {
923                     curmsg->pause_variable = var;
924                 } else {
925                     CSample *distribution = parse_distribution(true);
926 
927                     bool sanity_check = xp_get_bool("sanity_check", "pause", true);
928 
929                     double pause_duration = distribution->cdfInv(0.99);
930                     if (sanity_check && (pause_duration > INT_MAX)) {
931                         char percentile[100];
932                         char desc[100];
933 
934                         distribution->timeDescr(desc, sizeof(desc));
935                         time_string(pause_duration, percentile, sizeof(percentile));
936 
937                         ERROR("The distribution %s has a 99th percentile of %s, which is larger than INT_MAX.  You should chose different parameters.", desc, percentile);
938                     }
939 
940                     curmsg->pause_distribution = distribution;
941                     /* Update scenario duration with max duration */
942                     duration += (int)pause_duration;
943                 }
944             } else if(!strcmp(elem, "nop")) {
945                 checkOptionalRecv(elem, scenario_file_cursor);
946                 /* Does nothing at SIP level.  This message type can be used to handle
947                  * actions, increment counters, or for RTDs. */
948                 curmsg->M_type = MSG_TYPE_NOP;
949             } else if(!strcmp(elem, "recvCmd")) {
950                 curmsg->M_type = MSG_TYPE_RECVCMD;
951                 curmsg->optional = xp_get_optional("optional", "recv");
952                 last_recv_optional = curmsg->optional;
953 
954                 /* 3pcc extended mode */
955                 if ((cptr = xp_get_value("src"))) {
956                     curmsg->peer_src = strdup(cptr);
957                 } else if (extendedTwinSippMode) {
958                     ERROR("You must specify a 'src' for recvCmd when using extended 3pcc mode!");
959                 }
960             } else if(!strcmp(elem, "sendCmd")) {
961                 checkOptionalRecv(elem, scenario_file_cursor);
962                 curmsg->M_type = MSG_TYPE_SENDCMD;
963                 /* Sent messages descriptions */
964 
965                 /* 3pcc extended mode */
966                 if ((cptr = xp_get_value("dest"))) {
967                     peer = strdup(cptr);
968                     curmsg->peer_dest = peer;
969                     peer_map::iterator peer_it;
970                     peer_it = peers.find(peer_map::key_type(peer));
971                     if(peer_it == peers.end())
972                         /* the peer (slave or master)
973                         has not been added in the map
974                         (first occurrence in the scenario) */
975                     {
976                         T_peer_infos infos = {};
977                         infos.peer_socket = 0;
978                         strncpy(infos.peer_host, get_peer_addr(peer), sizeof(infos.peer_host) - 1);
979                         peers[std::string(peer)] = infos;
980                     }
981                 } else if (extendedTwinSippMode) {
982                     ERROR("You must specify a 'dest' for sendCmd with extended 3pcc mode!");
983                 }
984 
985                 if (!(ptr = xp_get_cdata())) {
986                     ERROR("No CDATA in 'sendCmd' section of xml scenario file");
987                 }
988                 char *msg = clean_cdata(ptr);
989 
990                 curmsg -> M_sendCmdData = new SendingMessage(this, msg, true /* skip sanity */);
991                 free(msg);
992             } else {
993                 ERROR("Unknown element '%s' in xml scenario file", elem);
994             }
995 
996             getCommonAttributes(curmsg);
997         } /** end * Message case */
998         xp_close_element();
999     } // end while
1000 
1001     free(method_list);
1002 
1003     str_int_map::iterator label_it = labelMap.find("_unexp.main");
1004     if (label_it != labelMap.end()) {
1005         unexpected_jump = label_it->second;
1006     } else {
1007         unexpected_jump = -1;
1008     }
1009     retaddr = find_var("_unexp.retaddr");
1010     pausedaddr = find_var("_unexp.pausedaddr");
1011 
1012     /* Patch up the labels. */
1013     apply_labels(messages, labelMap);
1014     apply_labels(initmessages, initLabelMap);
1015 
1016     /* Some post-scenario loading validation. */
1017     stats->validateRtds();
1018 
1019     /* Make sure that all variables are used more than once. */
1020     validate_variable_usage();
1021 
1022     /* Make sure that all started transactions have responses, and vice versa. */
1023     validate_txn_usage();
1024 
1025     if (messages.size() == 0) {
1026         ERROR("Did not find any messages inside of scenario!");
1027     }
1028 }
1029 
runInit()1030 void scenario::runInit()
1031 {
1032     call *initcall;
1033     if (initmessages.size() > 0) {
1034         initcall = new call(main_scenario, NULL, NULL, "///main-init", 0, false, false, true);
1035         initcall->run();
1036     }
1037 }
1038 
clear_int_str(int_str_map m)1039 void clear_int_str(int_str_map m)
1040 {
1041     for(int_str_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1042         free(it->second);
1043         m.erase(it);
1044     }
1045 }
1046 
clear_str_int(str_int_map m)1047 void clear_str_int(str_int_map m)
1048 {
1049     for(str_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1050         m.erase(it);
1051     }
1052 }
1053 
clear_int_int(int_int_map m)1054 void clear_int_int(int_int_map m)
1055 {
1056     for(int_int_map::iterator it = m.begin(); it != m.end(); it = m.begin()) {
1057         m.erase(it);
1058     }
1059 }
1060 
~scenario()1061 scenario::~scenario()
1062 {
1063     for (msgvec::iterator i = messages.begin(); i != messages.end(); i++) {
1064         delete *i;
1065     }
1066     messages.clear();
1067 
1068     free(name);
1069 
1070     allocVars->putTable();
1071     delete stats;
1072 
1073     for (unsigned int i = 0; i < transactions.size(); i++) {
1074         free(transactions[i].name);
1075     }
1076     transactions.clear();
1077 
1078     clear_str_int(labelMap);
1079     clear_str_int(initLabelMap);
1080     clear_str_int(txnMap);
1081 }
1082 
parse_distribution(bool oldstyle=false)1083 CSample *parse_distribution(bool oldstyle = false)
1084 {
1085     CSample *distribution;
1086     const char *distname;
1087     const char *ptr = 0;
1088 
1089     if(!(distname = xp_get_value("distribution"))) {
1090         if (!oldstyle) {
1091             ERROR("statistically distributed actions or pauses requires 'distribution' parameter");
1092         }
1093         if ((ptr = xp_get_value("normal"))) {
1094             distname = "normal";
1095         } else if ((ptr = xp_get_value("exponential"))) {
1096             distname = "exponential";
1097         } else if ((ptr = xp_get_value("lognormal"))) {
1098             distname = "lognormal";
1099         } else if ((ptr = xp_get_value("weibull"))) {
1100             distname = "weibull";
1101         } else if ((ptr = xp_get_value("pareto"))) {
1102             distname = "pareto";
1103         } else if ((ptr = xp_get_value("gamma"))) {
1104             distname = "gamma";
1105         } else if ((ptr = xp_get_value("min"))) {
1106             distname = "uniform";
1107         } else if ((ptr = xp_get_value("max"))) {
1108             distname = "uniform";
1109         } else if ((ptr = xp_get_value("milliseconds"))) {
1110             double val = get_double(ptr, "Pause milliseconds");
1111             return new CFixed(val);
1112         } else {
1113             return new CDefaultPause();
1114         }
1115     }
1116 
1117     if (!strcmp(distname, "fixed")) {
1118         double value = xp_get_double("value", "Fixed distribution");
1119         distribution = new CFixed(value);
1120     } else if (!strcmp(distname, "uniform")) {
1121         double min = xp_get_double("min", "Uniform distribution");
1122         double max = xp_get_double("max", "Uniform distribution");
1123         distribution = new CUniform(min, max);
1124 #ifdef HAVE_GSL
1125     } else if (!strcmp(distname, "normal")) {
1126         double mean = xp_get_double("mean", "Normal distribution");
1127         double stdev = xp_get_double("stdev", "Normal distribution");
1128         distribution = new CNormal(mean, stdev);
1129     } else if (!strcmp(distname, "lognormal")) {
1130         double mean = xp_get_double("mean", "Lognormal distribution");
1131         double stdev = xp_get_double("stdev", "Lognormal distribution");
1132         distribution = new CLogNormal(mean, stdev);
1133     } else if (!strcmp(distname, "exponential")) {
1134         double mean = xp_get_double("mean", "Exponential distribution");
1135         distribution = new CExponential(mean);
1136     } else if (!strcmp(distname, "weibull")) {
1137         double lambda = xp_get_double("lambda", "Weibull distribution");
1138         double k = xp_get_double("k", "Weibull distribution");
1139         distribution = new CWeibull(lambda, k);
1140     } else if (!strcmp(distname, "pareto")) {
1141         double k = xp_get_double("k", "Pareto distribution");
1142         double xsubm = xp_get_double("x_m", "Pareto distribution");
1143         distribution = new CPareto(k, xsubm);
1144     } else if (!strcmp(distname, "gpareto")) {
1145         double shape = xp_get_double("shape", "Generalized Pareto distribution");
1146         double scale = xp_get_double("scale", "Generalized Pareto distribution");
1147         double location = xp_get_double("location", "Generalized Pareto distribution");
1148         distribution = new CGPareto(shape, scale, location);
1149     } else if (!strcmp(distname, "gamma")) {
1150         double k = xp_get_double("k", "Gamma distribution");
1151         double theta = xp_get_double("theta", "Gamma distribution");
1152         distribution = new CGamma(k, theta);
1153     } else if (!strcmp(distname, "negbin")) {
1154         double n = xp_get_double("n", "Negative Binomial distribution");
1155         double p = xp_get_double("p", "Negative Binomial distribution");
1156         distribution = new CNegBin(n, p);
1157 #else
1158     } else if (!strcmp(distname, "normal")
1159                || !strcmp(distname, "lognormal")
1160                || !strcmp(distname, "exponential")
1161                || !strcmp(distname, "pareto")
1162                || !strcmp(distname, "gamma")
1163                || !strcmp(distname, "negbin")
1164                || !strcmp(distname, "weibull")) {
1165         ERROR("The distribution '%s' is only available with GSL.", distname);
1166 #endif
1167     } else {
1168         ERROR("Unknown distribution: %s\n", ptr);
1169     }
1170 
1171     return distribution;
1172 }
1173 
1174 
1175 
1176 /* 3pcc extended mode:
1177    get the correspondances between
1178    slave and master names and their
1179    addresses */
1180 
parse_slave_cfg()1181 void parse_slave_cfg()
1182 {
1183     FILE * f;
1184     char line[MAX_PEER_SIZE];
1185     char * temp_peer;
1186     char * temp_host;
1187     char * peer_host;
1188 
1189     f = fopen(slave_cfg_file, "r");
1190     if(f) {
1191         while (fgets(line, MAX_PEER_SIZE, f) != NULL) {
1192             temp_peer = strtok(line, ";");
1193             if (!temp_peer)
1194                 continue;
1195 
1196             temp_host = strtok(NULL, ";");
1197             if (!temp_host)
1198                 continue;
1199 
1200             peer_host = strdup(temp_host);
1201             if (!peer_host)
1202                 ERROR("Cannot allocate memory!\n");
1203 
1204             peer_addrs[std::string(temp_peer)] = peer_host;
1205         }
1206     } else {
1207         ERROR("Can not open slave_cfg file %s\n", slave_cfg_file);
1208     }
1209 
1210     fclose(f);
1211 }
1212 
1213 // Determine in which mode the sipp tool has been
1214 // launched (client, server, 3pcc client, 3pcc server, 3pcc extended master or slave)
computeSippMode()1215 void scenario::computeSippMode()
1216 {
1217     bool isRecvCmdFound = false;
1218     bool isSendCmdFound = false;
1219 
1220     creationMode = -1;
1221     sendMode = -1;
1222     thirdPartyMode = MODE_3PCC_NONE;
1223 
1224     assert(messages.size() > 0);
1225 
1226     for(unsigned int i=0; i<messages.size(); i++) {
1227         switch(messages[i]->M_type) {
1228         case MSG_TYPE_PAUSE:
1229         case MSG_TYPE_NOP:
1230             /* Allow pauses or nops to go first. */
1231             continue;
1232         case MSG_TYPE_SEND:
1233             if (sendMode == -1) {
1234                 sendMode = MODE_CLIENT;
1235             }
1236             if (creationMode == -1) {
1237                 creationMode = MODE_CLIENT;
1238             }
1239             break;
1240 
1241         case MSG_TYPE_RECV:
1242             if (sendMode == -1) {
1243                 sendMode = MODE_SERVER;
1244             }
1245             if (creationMode == -1) {
1246                 creationMode = MODE_SERVER;
1247             }
1248             break;
1249         case MSG_TYPE_SENDCMD:
1250             isSendCmdFound = true;
1251             if (creationMode == -1) {
1252                 creationMode = MODE_CLIENT;
1253             }
1254             if(!isRecvCmdFound) {
1255                 if (creationMode == MODE_SERVER) {
1256                     /*
1257                      * If it is a server already, then start it in
1258                      * 3PCC A passive mode
1259                      */
1260                     if(twinSippMode) {
1261                         thirdPartyMode = MODE_3PCC_A_PASSIVE;
1262                     } else if (extendedTwinSippMode) {
1263                         thirdPartyMode = MODE_MASTER_PASSIVE;
1264                     }
1265                 } else {
1266                     if(twinSippMode) {
1267                         thirdPartyMode = MODE_3PCC_CONTROLLER_A;
1268                     } else if (extendedTwinSippMode) {
1269                         thirdPartyMode = MODE_MASTER;
1270                     }
1271                 }
1272                 if((thirdPartyMode == MODE_MASTER_PASSIVE || thirdPartyMode == MODE_MASTER) && !master_name) {
1273                     ERROR("Inconsistency between command line and scenario: master scenario but -master option not set\n");
1274                 }
1275                 if(!twinSippMode && !extendedTwinSippMode)
1276                     ERROR("sendCmd message found in scenario but no twin sipp"
1277                           " address has been passed! Use -3pcc option or 3pcc extended mode.\n");
1278             }
1279             break;
1280 
1281         case MSG_TYPE_RECVCMD:
1282             if (creationMode == -1) {
1283                 creationMode = MODE_SERVER;
1284             }
1285             isRecvCmdFound = true;
1286             if(!isSendCmdFound) {
1287                 if(twinSippMode) {
1288                     thirdPartyMode = MODE_3PCC_CONTROLLER_B;
1289                 } else if(extendedTwinSippMode) {
1290                     thirdPartyMode = MODE_SLAVE;
1291                     if(!slave_number) {
1292                         ERROR("Inconsistency between command line and scenario: slave scenario but -slave option not set\n");
1293                     } else {
1294                         thirdPartyMode = MODE_SLAVE;
1295                     }
1296                 }
1297                 if(!twinSippMode && !extendedTwinSippMode)
1298                     ERROR("recvCmd message found in scenario but no "
1299                           "twin sipp address has been passed! Use "
1300                           "-3pcc option\n");
1301             }
1302             break;
1303         default:
1304             break;
1305         }
1306     }
1307     if(creationMode == -1)
1308         ERROR("Unable to determine creation mode of the tool (server, client)\n");
1309     if(sendMode == -1)
1310         ERROR("Unable to determine send mode of the tool (server, client)\n");
1311 }
1312 
handle_rhs(CAction * tmpAction,const char * what)1313 void scenario::handle_rhs(CAction *tmpAction, const char *what)
1314 {
1315     if (xp_get_value("value")) {
1316         tmpAction->setDoubleValue(xp_get_double("value", what));
1317         if (xp_get_value("variable")) {
1318             ERROR("Value and variable are mutually exclusive for %s action!", what);
1319         }
1320     } else if (xp_get_value("variable")) {
1321         tmpAction->setVarInId(xp_get_var("variable", what));
1322         if (xp_get_value("value")) {
1323             ERROR("Value and variable are mutually exclusive for %s action!", what);
1324         }
1325     } else {
1326         ERROR("No value or variable defined for %s action!", what);
1327     }
1328 }
1329 
handle_arithmetic(CAction * tmpAction,const char * what)1330 void scenario::handle_arithmetic(CAction *tmpAction, const char *what)
1331 {
1332     tmpAction->setVarId(xp_get_var("assign_to", what));
1333     handle_rhs(tmpAction, what);
1334 }
1335 
parseAction(CActions * actions)1336 void scenario::parseAction(CActions *actions)
1337 {
1338     char *        actionElem;
1339     unsigned int recvScenarioLen = 0;
1340     char *        currentRegExp = NULL;
1341     char **       currentTabVarName = NULL;
1342     int           currentNbVarNames;
1343     int           sub_currentNbVarId;
1344     char* ptr;
1345     const char* cptr;
1346 
1347     while((actionElem = xp_open_element(recvScenarioLen))) {
1348         CAction *tmpAction = new CAction(this);
1349 
1350         if(!strcmp(actionElem, "ereg")) {
1351             ptr = xp_get_string("regexp", "ereg");
1352 
1353             // keeping regexp expression in memory
1354             if(currentRegExp != NULL)
1355                 delete[] currentRegExp;
1356             currentRegExp = new char[strlen(ptr)+1];
1357             xp_unescape(ptr, currentRegExp);
1358             tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_REGEXP);
1359 
1360             // warning - although these are detected for both msg and hdr
1361             // they are only implemented for search_in="hdr"
1362             tmpAction->setCaseIndep(xp_get_bool("case_indep", "ereg", false));
1363             tmpAction->setHeadersOnly(xp_get_bool("start_line", "ereg", false));
1364 
1365             free(ptr);
1366             if ((cptr = xp_get_value("search_in"))) {
1367                 tmpAction->setOccurrence(1);
1368 
1369                 if (strcmp(cptr, "msg") == 0) {
1370                     tmpAction->setLookingPlace(CAction::E_LP_MSG);
1371                     tmpAction->setLookingChar (NULL);
1372                 } else if (strcmp(cptr, "body") == 0) {
1373                     tmpAction->setLookingPlace(CAction::E_LP_BODY);
1374                     tmpAction->setLookingChar (NULL);
1375                 } else if (strcmp(cptr, "var") == 0) {
1376                     tmpAction->setVarInId(xp_get_var("variable", "ereg"));
1377                     tmpAction->setLookingPlace(CAction::E_LP_VAR);
1378                 } else if (strcmp(cptr, "hdr") == 0) {
1379                     cptr = xp_get_value("header");
1380                     if (!cptr || !strlen(cptr)) {
1381                         ERROR("search_in=\"hdr\" requires header field");
1382                     }
1383                     tmpAction->setLookingPlace(CAction::E_LP_HDR);
1384                     tmpAction->setLookingChar(cptr);
1385                     if ((cptr = xp_get_value("occurrence"))) {
1386                         tmpAction->setOccurrence(atol(cptr));
1387                     } else if ((cptr = xp_get_value("occurence"))) {
1388                         /* old misspelling */
1389                         tmpAction->setOccurrence(atol(cptr));
1390                     }
1391                 } else {
1392                     ERROR("Unknown search_in value %s", cptr);
1393                 }
1394             } else {
1395                 tmpAction->setLookingPlace(CAction::E_LP_MSG);
1396                 tmpAction->setLookingChar(NULL);
1397             } // end if-else search_in
1398 
1399             if (xp_get_value("check_it")) {
1400                 tmpAction->setCheckIt(xp_get_bool("check_it", "ereg", false));
1401                 if (xp_get_value("check_it_inverse")) {
1402                     ERROR("Can not have both check_it and check_it_inverse for ereg!");
1403                 }
1404             } else {
1405                 tmpAction->setCheckItInverse(xp_get_bool("check_it_inverse", "ereg", false));
1406             }
1407 
1408             if (!(ptr = xp_get_value("assign_to"))) {
1409                 ERROR("assign_to value is missing");
1410             }
1411 
1412             createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
1413 
1414             int varId = get_var(currentTabVarName[0], "assign_to");
1415             tmpAction->setVarId(varId);
1416 
1417             tmpAction->setRegExp(currentRegExp);
1418             if (currentNbVarNames > 1 ) {
1419                 sub_currentNbVarId = currentNbVarNames - 1 ;
1420                 tmpAction->setNbSubVarId(sub_currentNbVarId);
1421 
1422                 for(int i=1; i<= sub_currentNbVarId; i++) {
1423                     int varId = get_var(currentTabVarName[i], "sub expression assign_to");
1424                     tmpAction->setSubVarId(varId);
1425                 }
1426             }
1427 
1428             freeStringTable(currentTabVarName, currentNbVarNames);
1429 
1430             if(currentRegExp != NULL) {
1431                 delete[] currentRegExp;
1432             }
1433             currentRegExp = NULL;
1434         } /* end !strcmp(actionElem, "ereg") */ else if(!strcmp(actionElem, "log")) {
1435             ptr = xp_get_string("message", "log");
1436             tmpAction->setMessage(ptr);
1437             free(ptr);
1438             tmpAction->setActionType(CAction::E_AT_LOG_TO_FILE);
1439         } else if(!strcmp(actionElem, "warning")) {
1440             ptr = xp_get_string("message", "warning");
1441             tmpAction->setMessage(ptr);
1442             free(ptr);
1443             tmpAction->setActionType(CAction::E_AT_LOG_WARNING);
1444         } else if(!strcmp(actionElem, "error")) {
1445             ptr = xp_get_string("message", "error");
1446             tmpAction->setMessage(ptr);
1447             free(ptr);
1448             tmpAction->setActionType(CAction::E_AT_LOG_ERROR);
1449         } else if(!strcmp(actionElem, "assign")) {
1450             tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_VALUE);
1451             handle_arithmetic(tmpAction, "assign");
1452         } else if(!strcmp(actionElem, "assignstr")) {
1453             tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_STRING);
1454             tmpAction->setVarId(xp_get_var("assign_to", "assignstr"));
1455             ptr = xp_get_string("value", "assignstr");
1456             tmpAction->setMessage(ptr);
1457             free(ptr);
1458         } else if(!strcmp(actionElem, "gettimeofday")) {
1459             tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_GETTIMEOFDAY);
1460 
1461             if (!(ptr = xp_get_value("assign_to"))) {
1462                 ERROR("assign_to value is missing");
1463             }
1464             createStringTable(ptr, &currentTabVarName, &currentNbVarNames);
1465             if (currentNbVarNames != 2 ) {
1466                 ERROR("The gettimeofday action requires two output variables!");
1467             }
1468             tmpAction->setNbSubVarId(1);
1469 
1470             int varId = get_var(currentTabVarName[0], "gettimeofday seconds assign_to");
1471             tmpAction->setVarId(varId);
1472             varId = get_var(currentTabVarName[1], "gettimeofday useconds assign_to");
1473             tmpAction->setSubVarId(varId);
1474 
1475             freeStringTable(currentTabVarName, currentNbVarNames);
1476         } else if(!strcmp(actionElem, "index")) {
1477             tmpAction->setVarId(xp_get_var("assign_to", "index"));
1478             tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_INDEX);
1479         } else if(!strcmp(actionElem, "jump")) {
1480             tmpAction->setActionType(CAction::E_AT_JUMP);
1481             handle_rhs(tmpAction, "jump");
1482         } else if(!strcmp(actionElem, "pauserestore")) {
1483             tmpAction->setActionType(CAction::E_AT_PAUSE_RESTORE);
1484             handle_rhs(tmpAction, "pauserestore");
1485         } else if(!strcmp(actionElem, "add")) {
1486             tmpAction->setActionType(CAction::E_AT_VAR_ADD);
1487             handle_arithmetic(tmpAction, "add");
1488         } else if(!strcmp(actionElem, "subtract")) {
1489             tmpAction->setActionType(CAction::E_AT_VAR_SUBTRACT);
1490             handle_arithmetic(tmpAction, "subtract");
1491         } else if(!strcmp(actionElem, "multiply")) {
1492             tmpAction->setActionType(CAction::E_AT_VAR_MULTIPLY);
1493             handle_arithmetic(tmpAction, "multiply");
1494         } else if(!strcmp(actionElem, "divide")) {
1495             tmpAction->setActionType(CAction::E_AT_VAR_DIVIDE);
1496             handle_arithmetic(tmpAction, "divide");
1497             if (tmpAction->getVarInId() == 0) {
1498                 if (tmpAction->getDoubleValue() == 0.0) {
1499                     ERROR("divide actions can not have a value of zero!");
1500                 }
1501             }
1502         } else if(!strcmp(actionElem, "sample")) {
1503             tmpAction->setVarId(xp_get_var("assign_to", "sample"));
1504             tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_SAMPLE);
1505             tmpAction->setDistribution(parse_distribution());
1506         } else if(!strcmp(actionElem, "todouble")) {
1507             tmpAction->setActionType(CAction::E_AT_VAR_TO_DOUBLE);
1508             tmpAction->setVarId(xp_get_var("assign_to", "todouble"));
1509             tmpAction->setVarInId(xp_get_var("variable", "todouble"));
1510         } else if(!strcmp(actionElem, "test")) {
1511             tmpAction->setVarId(xp_get_var("assign_to", "test"));
1512             tmpAction->setVarInId(xp_get_var("variable", "test"));
1513             if (xp_get_value("value")) {
1514                 tmpAction->setDoubleValue(xp_get_double("value", "test"));
1515                 if (xp_get_value("variable2")) {
1516                     ERROR("Can not have both a value and a variable2 for test!");
1517                 }
1518             } else {
1519                 tmpAction->setVarIn2Id(xp_get_var("variable2", "test"));
1520             }
1521             tmpAction->setActionType(CAction::E_AT_VAR_TEST);
1522             ptr = xp_get_string("compare", "test");
1523             if (!strcmp(ptr, "equal")) {
1524                 tmpAction->setComparator(CAction::E_C_EQ);
1525             } else if (!strcmp(ptr, "not_equal")) {
1526                 tmpAction->setComparator(CAction::E_C_NE);
1527             } else if (!strcmp(ptr, "greater_than")) {
1528                 tmpAction->setComparator(CAction::E_C_GT);
1529             } else if (!strcmp(ptr, "less_than")) {
1530                 tmpAction->setComparator(CAction::E_C_LT);
1531             } else if (!strcmp(ptr, "greater_than_equal")) {
1532                 tmpAction->setComparator(CAction::E_C_GEQ);
1533             } else if (!strcmp(ptr, "less_than_equal")) {
1534                 tmpAction->setComparator(CAction::E_C_LEQ);
1535             } else {
1536                 ERROR("Invalid 'compare' parameter: %s", ptr);
1537             }
1538             free(ptr);
1539         } else if(!strcmp(actionElem, "verifyauth")) {
1540             tmpAction->setVarId(xp_get_var("assign_to", "verifyauth"));
1541             char* username_ptr = xp_get_string("username", "verifyauth");
1542             char* password_ptr = xp_get_string("password", "verifyauth");
1543             tmpAction->setMessage(username_ptr, 0);
1544             tmpAction->setMessage(password_ptr, 1);
1545             tmpAction->setActionType(CAction::E_AT_VERIFY_AUTH);
1546             free(username_ptr);
1547             free(password_ptr);
1548             username_ptr = password_ptr = NULL;
1549         } else if(!strcmp(actionElem, "lookup")) {
1550             tmpAction->setVarId(xp_get_var("assign_to", "lookup"));
1551             tmpAction->setMessage(xp_get_string("file", "lookup"), 0);
1552             tmpAction->setMessage(xp_get_string("key", "lookup"), 1);
1553             tmpAction->setActionType(CAction::E_AT_LOOKUP);
1554         } else if(!strcmp(actionElem, "insert")) {
1555             tmpAction->setMessage(xp_get_string("file", "insert"), 0);
1556             tmpAction->setMessage(xp_get_string("value", "insert"), 1);
1557             tmpAction->setActionType(CAction::E_AT_INSERT);
1558         } else if(!strcmp(actionElem, "replace")) {
1559             tmpAction->setMessage(xp_get_string("file", "replace"), 0);
1560             tmpAction->setMessage(xp_get_string("line", "replace"), 1);
1561             tmpAction->setMessage(xp_get_string("value", "replace"), 2);
1562             tmpAction->setActionType(CAction::E_AT_REPLACE);
1563         } else if(!strcmp(actionElem, "setdest")) {
1564             tmpAction->setMessage(xp_get_string("host", actionElem), 0);
1565             tmpAction->setMessage(xp_get_string("port", actionElem), 1);
1566             tmpAction->setMessage(xp_get_string("protocol", actionElem), 2);
1567             tmpAction->setActionType(CAction::E_AT_SET_DEST);
1568         } else if(!strcmp(actionElem, "closecon")) {
1569             tmpAction->setActionType(CAction::E_AT_CLOSE_CON);
1570         } else if(!strcmp(actionElem, "strcmp")) {
1571             tmpAction->setVarId(xp_get_var("assign_to", "strcmp"));
1572             tmpAction->setVarInId(xp_get_var("variable", "strcmp"));
1573             if (xp_get_value("value")) {
1574                 tmpAction->setStringValue(xp_get_string("value", "strcmp"));
1575                 if (xp_get_value("variable2")) {
1576                     ERROR("Can not have both a value and a variable2 for strcmp!");
1577                 }
1578             } else {
1579                 tmpAction->setVarIn2Id(xp_get_var("variable2", "strcmp"));
1580             }
1581             tmpAction->setActionType(CAction::E_AT_VAR_STRCMP);
1582         } else if(!strcmp(actionElem, "trim")) {
1583             tmpAction->setVarId(xp_get_var("assign_to", "trim"));
1584             tmpAction->setActionType(CAction::E_AT_VAR_TRIM);
1585         } else if(!strcmp(actionElem, "exec")) {
1586             if ((ptr = xp_get_value("command"))) {
1587                 tmpAction->setActionType(CAction::E_AT_EXECUTE_CMD);
1588                 tmpAction->setMessage(ptr);
1589             } else if((cptr = xp_get_value("int_cmd"))) {
1590                 CAction::T_IntCmdType type(CAction::E_INTCMD_STOPCALL); /* assume the default */
1591 
1592                 if (strcmp(cptr, "stop_now") == 0) {
1593                     type = CAction::E_INTCMD_STOP_NOW;
1594                 } else if (strcmp(cptr, "stop_gracefully") == 0) {
1595                     type = CAction::E_INTCMD_STOP_ALL;
1596                 } else if (strcmp(cptr, "stop_call") == 0) {
1597                     type = CAction::E_INTCMD_STOPCALL;
1598                 }
1599 
1600                 /* the action is well formed, adding it in the */
1601                 /* tmpActionTable */
1602                 tmpAction->setActionType(CAction::E_AT_EXEC_INTCMD);
1603                 tmpAction->setIntCmd(type);
1604 #ifdef PCAPPLAY
1605             } else if ((cptr = xp_get_keyword_value("play_pcap_audio"))) {
1606                 tmpAction->setPcapArgs(cptr);
1607                 tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_AUDIO);
1608                 hasMedia = 1;
1609             } else if ((cptr = xp_get_keyword_value("play_pcap_image"))) {
1610                 tmpAction->setPcapArgs(cptr);
1611                 tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_IMAGE);
1612                 hasMedia = 1;
1613             } else if ((cptr = xp_get_keyword_value("play_pcap_video"))) {
1614                 tmpAction->setPcapArgs(cptr);
1615                 tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_VIDEO);
1616                 hasMedia = 1;
1617 #else
1618             } else if (xp_get_value("play_pcap_audio")) {
1619                 ERROR("Scenario specifies a play_pcap_audio action, but this version of SIPp does not have PCAP support");
1620             } else if (xp_get_value("play_pcap_image")) {
1621                 ERROR("Scenario specifies a play_pcap_image action, but this version of SIPp does not have PCAP support");
1622             } else if (xp_get_value("play_pcap_video")) {
1623                 ERROR("Scenario specifies a play_pcap_video action, but this version of SIPp does not have PCAP support");
1624 #endif
1625             } else if ((cptr = xp_get_value("rtp_stream"))) {
1626 #ifdef RTP_STREAM
1627                 hasMedia = 1;
1628                 if (strcmp(cptr, "pause") == 0) {
1629                     tmpAction->setActionType(CAction::E_AT_RTP_STREAM_PAUSE);
1630                 } else if (strcmp(cptr, "resume") == 0) {
1631                     tmpAction->setActionType(CAction::E_AT_RTP_STREAM_RESUME);
1632                 } else {
1633                     tmpAction->setRTPStreamActInfo(cptr);
1634                     tmpAction->setActionType(CAction::E_AT_RTP_STREAM_PLAY);
1635                 }
1636 #else
1637                 ERROR("Scenario specifies a rtp_stream action, but this version of SIPp does not have RTP stream support");
1638 #endif
1639             } else {
1640                 ERROR("illegal <exec> in the scenario\n");
1641             }
1642         } else {
1643             ERROR("Unknown action: %s", actionElem);
1644         }
1645 
1646         /* If the action was not well-formed, there should have already been an
1647          * ERROR declaration, thus it is safe to add it here at the end of the loop. */
1648         actions->setAction(tmpAction);
1649 
1650         xp_close_element();
1651         recvScenarioLen++;
1652     } // end while
1653 }
1654 
1655 // Action list for the message indexed by message_index in
1656 // the scenario
getActionForThisMessage(message * message)1657 void scenario::getActionForThisMessage(message *message)
1658 {
1659     char *        actionElem;
1660 
1661     if(!(actionElem = xp_open_element(0))) {
1662         return;
1663     }
1664     if(strcmp(actionElem, "action")) {
1665         return;
1666     }
1667 
1668     /* We actually have an action element. */
1669     if(message->M_actions != NULL) {
1670         ERROR("Duplicate action for %s index %d", message->desc, message->index);
1671     }
1672     message->M_actions = new CActions();
1673 
1674     parseAction(message->M_actions);
1675     xp_close_element();
1676 }
1677 
getBookKeeping(message * message)1678 void scenario::getBookKeeping(message *message)
1679 {
1680     const char *ptr;
1681 
1682     if ((ptr = xp_get_value("rtd"))) {
1683         message->stop_rtd = get_rtd(ptr, false);
1684     }
1685     if ((ptr = xp_get_value("repeat_rtd"))) {
1686         if (message->stop_rtd) {
1687             message->repeat_rtd = get_bool(ptr, "repeat_rtd");
1688         } else {
1689             ERROR("There is a repeat_rtd element without an rtd element");
1690         }
1691     }
1692 
1693     if ((ptr = xp_get_value("start_rtd"))) {
1694         message->start_rtd = get_rtd(ptr, true);
1695     }
1696 
1697     if ((ptr = xp_get_value("counter"))) {
1698         message->counter = get_counter(ptr, "counter");
1699     }
1700 }
1701 
getCommonAttributes(message * message)1702 void scenario::getCommonAttributes(message *message)
1703 {
1704     char *ptr;
1705 
1706     getBookKeeping(message);
1707     getActionForThisMessage(message);
1708 
1709     if((ptr = xp_get_value((char *)"lost"))) {
1710         message -> lost = get_double(ptr, "lost percentage");
1711         lose_packets = 1;
1712     }
1713 
1714     if((ptr = xp_get_value((char *)"crlf"))) {
1715         message -> crlf = 1;
1716     }
1717 
1718     if (xp_get_value("hiderest")) {
1719         hidedefault = xp_get_bool("hiderest", "hiderest");
1720     }
1721     message -> hide = xp_get_bool("hide", "hide", hidedefault);
1722     if((ptr = xp_get_value((char *)"display"))) {
1723         message -> display_str = strdup(ptr);
1724     }
1725 
1726     message -> condexec = xp_get_var("condexec", "condexec variable", -1);
1727     message -> condexec_inverse = xp_get_bool("condexec_inverse", "condexec_inverse", false);
1728 
1729     if ((ptr = xp_get_value("next"))) {
1730         if (found_timewait) {
1731             ERROR("next labels are not allowed in <timewait> elements.");
1732         }
1733         message->nextLabel = strdup(ptr);
1734         message->test = xp_get_var("test", "test variable", -1);
1735         if ( 0 != ( ptr = xp_get_value((char *)"chance") ) ) {
1736             float chance = get_double(ptr,"chance");
1737             /* probability of branch to next */
1738             if (( chance < 0.0 ) || (chance > 1.0 )) {
1739                 ERROR("Chance %s not in range [0..1]", ptr);
1740             }
1741             message -> chance = (int)((1.0-chance)*RAND_MAX);
1742         } else {
1743             message -> chance = 0; /* always */
1744         }
1745     }
1746 
1747     if ((ptr = xp_get_value((char *)"ontimeout"))) {
1748         if (found_timewait) {
1749             ERROR("ontimeout labels are not allowed in <timewait> elements.");
1750         }
1751         message -> onTimeoutLabel = strdup(ptr);
1752     }
1753 }
1754 
1755 // char* manipulation : create a int[] from a char*
1756 // test first is the char* is formed by int separeted by coma
1757 // and then create the table
1758 
isWellFormed(char * P_listeStr,int * nombre)1759 int isWellFormed(char * P_listeStr, int * nombre)
1760 {
1761     char * ptr = P_listeStr;
1762     int sizeOf;
1763     bool isANumber;
1764 
1765     (*nombre) = 0;
1766     sizeOf = strlen(P_listeStr);
1767     // getting the number
1768     if(sizeOf > 0) {
1769         // is the string well formed ? [0-9] [,]
1770         isANumber = false;
1771         for(int i=0; i<=sizeOf; i++) {
1772             switch(ptr[i]) {
1773             case ',':
1774                 if(isANumber == false) {
1775                     return(0);
1776                 } else {
1777                     (*nombre)++;
1778                 }
1779                 isANumber = false;
1780                 break;
1781             case '0':
1782             case '1':
1783             case '2':
1784             case '3':
1785             case '4':
1786             case '5':
1787             case '6':
1788             case '7':
1789             case '8':
1790             case '9':
1791                 isANumber = true;
1792                 break;
1793             case '\t':
1794             case ' ' :
1795                 break;
1796             case '\0':
1797                 if(isANumber == false) {
1798                     return(0);
1799                 } else {
1800                     (*nombre)++;
1801                 }
1802                 break;
1803             default:
1804                 return(0);
1805             }
1806         } // end for
1807     }
1808     return(1);
1809 }
1810 
createIntegerTable(char * P_listeStr,unsigned int ** listeInteger,int * sizeOfList)1811 int createIntegerTable(char * P_listeStr,
1812                        unsigned int ** listeInteger,
1813                        int * sizeOfList)
1814 {
1815     int nb=0;
1816     char * ptr = P_listeStr;
1817     char * ptr_prev = P_listeStr;
1818     unsigned int current_int;
1819 
1820     if(P_listeStr) {
1821         if(isWellFormed(P_listeStr, sizeOfList) == 1) {
1822             (*listeInteger) = new unsigned int[(*sizeOfList)];
1823             while((*ptr) != ('\0')) {
1824                 if((*ptr) == ',') {
1825                     sscanf(ptr_prev, "%u", &current_int);
1826                     if (nb<(*sizeOfList))
1827                         (*listeInteger)[nb] = current_int;
1828                     nb++;
1829                     ptr_prev = ptr+1;
1830                 }
1831                 ptr++;
1832             }
1833 
1834             // Read the last
1835             sscanf(ptr_prev, "%u", &current_int);
1836             if (nb<(*sizeOfList))
1837                 (*listeInteger)[nb] = current_int;
1838             nb++;
1839             return(1);
1840         }
1841         return(0);
1842     } else return(0);
1843 }
1844 
createStringTable(char * inputString,char *** stringList,int * sizeOfList)1845 int createStringTable(char * inputString, char *** stringList, int *sizeOfList)
1846 {
1847     if(!inputString) {
1848         return 0;
1849     }
1850 
1851     *stringList = NULL;
1852     *sizeOfList = 0;
1853 
1854     do {
1855         char *p = strchr(inputString, ',');
1856         if (p) {
1857             *p++ = '\0';
1858         }
1859 
1860         *stringList = (char **)realloc(*stringList, sizeof(char *) * (*sizeOfList + 1));
1861         (*stringList)[*sizeOfList] = strdup(inputString);
1862         (*sizeOfList)++;
1863 
1864         inputString = p;
1865     } while (inputString);
1866 
1867     return 1;
1868 }
1869 
freeStringTable(char ** stringList,int sizeOfList)1870 void freeStringTable(char ** stringList, int sizeOfList)
1871 {
1872     for (int i = 0; i < sizeOfList; i++) {
1873         free(stringList[i]);
1874     }
1875     free(stringList);
1876 }
1877 
1878 /* These are the names of the scenarios, they must match the default_scenario table. */
1879 const char *scenario_table[] = {
1880     "uac",
1881     "uas",
1882     "regexp",
1883     "3pcc-C-A",
1884     "3pcc-C-B",
1885     "3pcc-A",
1886     "3pcc-B",
1887     "branchc",
1888     "branchs",
1889     "uac_pcap",
1890     "ooc_default",
1891     "ooc_dummy",
1892 };
1893 
find_scenario(const char * scenario)1894 int find_scenario(const char *scenario)
1895 {
1896     int i, max;
1897     max = sizeof(scenario_table)/sizeof(scenario_table[0]);
1898 
1899     for (i = 0; i < max; i++) {
1900         if (!strcmp(scenario_table[i], scenario)) {
1901             return i;
1902         }
1903     }
1904 
1905     ERROR("Invalid default scenario name '%s'.\n", scenario);
1906     return -1;
1907 }
1908 
1909 // TIP: to integrate an existing XML scenario, use the following sed line:
1910 // cat ../3pcc-controller-B.xml | sed -e 's/\"/\\\"/g' -e 's/\(.*\)/\"\1\\n\"/'
1911 const char * default_scenario [] = {
1912     /************* Default_scenario[0] ***************/
1913     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
1914     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
1915     "\n"
1916     "<!-- This program is free software; you can redistribute it and/or      -->\n"
1917     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
1918     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
1919     "<!-- License, or (at your option) any later version.                    -->\n"
1920     "<!--                                                                    -->\n"
1921     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
1922     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
1923     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
1924     "<!-- GNU General Public License for more details.                       -->\n"
1925     "<!--                                                                    -->\n"
1926     "<!-- You should have received a copy of the GNU General Public License  -->\n"
1927     "<!-- along with this program; if not, write to the                      -->\n"
1928     "<!-- Free Software Foundation, Inc.,                                    -->\n"
1929     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
1930     "<!--                                                                    -->\n"
1931     "<!--                 Sipp default 'uac' scenario.                       -->\n"
1932     "<!--                                                                    -->\n"
1933     "\n"
1934     "<scenario name=\"Basic Sipstone UAC\">\n"
1935     "  <!-- In client mode (sipp placing calls), the Call-ID MUST be         -->\n"
1936     "  <!-- generated by sipp. To do so, use [call_id] keyword.                -->\n"
1937     "  <send retrans=\"500\">\n"
1938     "    <![CDATA[\n"
1939     "\n"
1940     "      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1941     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1942     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1943     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>\n"
1944     "      Call-ID: [call_id]\n"
1945     "      CSeq: 1 INVITE\n"
1946     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
1947     "      Max-Forwards: 70\n"
1948     "      Subject: Performance Test\n"
1949     "      Content-Type: application/sdp\n"
1950     "      Content-Length: [len]\n"
1951     "\n"
1952     "      v=0\n"
1953     "      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
1954     "      s=-\n"
1955     "      c=IN IP[media_ip_type] [media_ip]\n"
1956     "      t=0 0\n"
1957     "      m=audio [media_port] RTP/AVP 0\n"
1958     "      a=rtpmap:0 PCMU/8000\n"
1959     "\n"
1960     "    ]]>\n"
1961     "  </send>\n"
1962     "\n"
1963     "  <recv response=\"100\"\n"
1964     "        optional=\"true\">\n"
1965     "  </recv>\n"
1966     "\n"
1967     "  <recv response=\"180\" optional=\"true\">\n"
1968     "  </recv>\n"
1969     "\n"
1970     "  <recv response=\"183\" optional=\"true\">\n"
1971     "  </recv>\n"
1972     "\n"
1973     "  <!-- By adding rrs=\"true\" (Record Route Sets), the route sets         -->\n"
1974     "  <!-- are saved and used for following messages sent. Useful to test   -->\n"
1975     "  <!-- against stateful SIP proxies/B2BUAs.                             -->\n"
1976     "  <recv response=\"200\" rtd=\"true\">\n"
1977     "  </recv>\n"
1978     "\n"
1979     "  <!-- Packet lost can be simulated in any send/recv message by         -->\n"
1980     "  <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent.       -->\n"
1981     "  <send>\n"
1982     "    <![CDATA[\n"
1983     "\n"
1984     "      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
1985     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
1986     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
1987     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
1988     "      Call-ID: [call_id]\n"
1989     "      CSeq: 1 ACK\n"
1990     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
1991     "      Max-Forwards: 70\n"
1992     "      Subject: Performance Test\n"
1993     "      Content-Length: 0\n"
1994     "\n"
1995     "    ]]>\n"
1996     "  </send>\n"
1997     "\n"
1998     "  <!-- This delay can be customized by the -d command-line option       -->\n"
1999     "  <!-- or by adding a 'milliseconds = \"value\"' option here.             -->\n"
2000     "  <pause/>\n"
2001     "\n"
2002     "  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2003     "  <send retrans=\"500\">\n"
2004     "    <![CDATA[\n"
2005     "\n"
2006     "      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2007     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2008     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]\n"
2009     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2010     "      Call-ID: [call_id]\n"
2011     "      CSeq: 2 BYE\n"
2012     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2013     "      Max-Forwards: 70\n"
2014     "      Subject: Performance Test\n"
2015     "      Content-Length: 0\n"
2016     "\n"
2017     "    ]]>\n"
2018     "  </send>\n"
2019     "\n"
2020     "  <recv response=\"200\" crlf=\"true\">\n"
2021     "  </recv>\n"
2022     "\n"
2023     "  <!-- definition of the response time repartition table (unit is ms)   -->\n"
2024     "  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2025     "\n"
2026     "  <!-- definition of the call length repartition table (unit is ms)     -->\n"
2027     "  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2028     "\n"
2029     "</scenario>\n"
2030     "\n"
2031     ,
2032 
2033     /************* Default_scenario[1] ***************/
2034     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2035     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2036     "\n"
2037     "<!-- This program is free software; you can redistribute it and/or      -->\n"
2038     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
2039     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2040     "<!-- License, or (at your option) any later version.                    -->\n"
2041     "<!--                                                                    -->\n"
2042     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
2043     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
2044     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
2045     "<!-- GNU General Public License for more details.                       -->\n"
2046     "<!--                                                                    -->\n"
2047     "<!-- You should have received a copy of the GNU General Public License  -->\n"
2048     "<!-- along with this program; if not, write to the                      -->\n"
2049     "<!-- Free Software Foundation, Inc.,                                    -->\n"
2050     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
2051     "<!--                                                                    -->\n"
2052     "<!--                 Sipp default 'uas' scenario.                       -->\n"
2053     "<!--                                                                    -->\n"
2054     "\n"
2055     "<scenario name=\"Basic UAS responder\">\n"
2056     "  <!-- By adding rrs=\"true\" (Record Route Sets), the route sets         -->\n"
2057     "  <!-- are saved and used for following messages sent. Useful to test   -->\n"
2058     "  <!-- against stateful SIP proxies/B2BUAs.                             -->\n"
2059     "  <recv request=\"INVITE\" crlf=\"true\">\n"
2060     "  </recv>\n"
2061     "\n"
2062     "  <!-- The '[last_*]' keyword is replaced automatically by the          -->\n"
2063     "  <!-- specified header if it was present in the last message received  -->\n"
2064     "  <!-- (except if it was a retransmission). If the header was not       -->\n"
2065     "  <!-- present or if no message has been received, the '[last_*]'       -->\n"
2066     "  <!-- keyword is discarded, and all bytes until the end of the line    -->\n"
2067     "  <!-- are also discarded.                                              -->\n"
2068     "  <!--                                                                  -->\n"
2069     "  <!-- If the specified header was present several times in the         -->\n"
2070     "  <!-- message, all occurrences are concatenated (CRLF separated)       -->\n"
2071     "  <!-- to be used in place of the '[last_*]' keyword.                   -->\n"
2072     "\n"
2073     "  <send>\n"
2074     "    <![CDATA[\n"
2075     "\n"
2076     "      SIP/2.0 180 Ringing\n"
2077     "      [last_Via:]\n"
2078     "      [last_From:]\n"
2079     "      [last_To:];tag=[pid]SIPpTag01[call_number]\n"
2080     "      [last_Call-ID:]\n"
2081     "      [last_CSeq:]\n"
2082     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2083     "      Content-Length: 0\n"
2084     "\n"
2085     "    ]]>\n"
2086     "  </send>\n"
2087     "\n"
2088     "  <send retrans=\"500\">\n"
2089     "    <![CDATA[\n"
2090     "\n"
2091     "      SIP/2.0 200 OK\n"
2092     "      [last_Via:]\n"
2093     "      [last_From:]\n"
2094     "      [last_To:];tag=[pid]SIPpTag01[call_number]\n"
2095     "      [last_Call-ID:]\n"
2096     "      [last_CSeq:]\n"
2097     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2098     "      Content-Type: application/sdp\n"
2099     "      Content-Length: [len]\n"
2100     "\n"
2101     "      v=0\n"
2102     "      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2103     "      s=-\n"
2104     "      c=IN IP[media_ip_type] [media_ip]\n"
2105     "      t=0 0\n"
2106     "      m=audio [media_port] RTP/AVP 0\n"
2107     "      a=rtpmap:0 PCMU/8000\n"
2108     "\n"
2109     "    ]]>\n"
2110     "  </send>\n"
2111     "\n"
2112     "  <recv request=\"ACK\"\n"
2113     "        optional=\"true\"\n"
2114     "        rtd=\"true\"\n"
2115     "        crlf=\"true\">\n"
2116     "  </recv>\n"
2117     "\n"
2118     "  <recv request=\"BYE\">\n"
2119     "  </recv>\n"
2120     "\n"
2121     "  <send>\n"
2122     "    <![CDATA[\n"
2123     "\n"
2124     "      SIP/2.0 200 OK\n"
2125     "      [last_Via:]\n"
2126     "      [last_From:]\n"
2127     "      [last_To:]\n"
2128     "      [last_Call-ID:]\n"
2129     "      [last_CSeq:]\n"
2130     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2131     "      Content-Length: 0\n"
2132     "\n"
2133     "    ]]>\n"
2134     "  </send>\n"
2135     "\n"
2136     "  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
2137     "  <!-- able to retransmit it if we receive the BYE again.               -->\n"
2138     "  <timewait milliseconds=\"4000\"/>\n"
2139     "\n"
2140     "\n"
2141     "  <!-- definition of the response time repartition table (unit is ms)   -->\n"
2142     "  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2143     "\n"
2144     "  <!-- definition of the call length repartition table (unit is ms)     -->\n"
2145     "  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2146     "\n"
2147     "</scenario>\n"
2148     "\n",
2149 
2150     /************* Default_scenario[2] ***************/
2151     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2152     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2153     "\n"
2154     "<!-- This program is free software; you can redistribute it and/or      -->\n"
2155     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
2156     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2157     "<!-- License, or (at your option) any later version.                    -->\n"
2158     "<!--                                                                    -->\n"
2159     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
2160     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
2161     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
2162     "<!-- GNU General Public License for more details.                       -->\n"
2163     "<!--                                                                    -->\n"
2164     "<!-- You should have received a copy of the GNU General Public License  -->\n"
2165     "<!-- along with this program; if not, write to the                      -->\n"
2166     "<!-- Free Software Foundation, Inc.,                                    -->\n"
2167     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
2168     "<!--                                                                    -->\n"
2169     "<!--                 Sipp default 'regexp client' scenario.             -->\n"
2170     "<!--                                                                    -->\n"
2171     "\n"
2172     "<scenario name=\"Client with regexp scenario\">\n"
2173     "  <send retrans=\"500\">\n"
2174     "    <![CDATA[\n"
2175     "\n"
2176     "      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2177     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2178     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2179     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>\n"
2180     "      Call-ID: [call_id]\n"
2181     "      CSeq: 1 INVITE\n"
2182     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2183     "      Max-Forwards: 70\n"
2184     "      Subject: Performance Test\n"
2185     "      Content-Type: application/sdp\n"
2186     "      Content-Length: [len]\n"
2187     "\n"
2188     "      v=0\n"
2189     "      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2190     "      s=-\n"
2191     "      c=IN IP[media_ip_type] [media_ip]\n"
2192     "      t=0 0\n"
2193     "      m=audio [media_port] RTP/AVP 0\n"
2194     "      a=rtpmap:0 PCMU/8000\n"
2195     "\n"
2196     "    ]]>\n"
2197     "  </send>\n"
2198     "\n"
2199     "  <recv response=\"100\"\n"
2200     "        optional=\"true\">\n"
2201     "  </recv>\n"
2202     "\n"
2203     "  <recv response=\"180\" optional=\"true\">\n"
2204     "  </recv>\n"
2205     "  <recv response=\"183\" optional=\"true\">\n"
2206     "  </recv>\n"
2207     "\n"
2208     "  <recv response=\"200\" start_rtd=\"true\">\n"
2209     "    <!-- Definition of regexp in the action tag. The regexp must follow -->\n"
2210     "    <!-- the Posix Extended standard (POSIX 1003.2), see:               -->\n"
2211     "    <!--                                                                -->\n"
2212     "    <!--   http://www.opengroup.org/onlinepubs/007908799/xbd/re.html    -->\n"
2213     "    <!--                                                                -->\n"
2214     "    <!-- regexp    : Contain the regexp to use for matching the         -->\n"
2215     "    <!--             received message                                   -->\n"
2216     "    <!--             MANDATORY                                          -->\n"
2217     "    <!-- search_in : msg (try to match against the entire message)      -->\n"
2218     "    <!--           : hdr (try to match against a specific SIP header    -->\n"
2219     "    <!--             (passed in the header tag)                         -->\n"
2220     "    <!--             OPTIONAL - default value : msg                     -->\n"
2221     "    <!-- header    : Header to try to match against.                    -->\n"
2222     "    <!--             Only used when the search_in tag is set to hdr     -->\n"
2223     "    <!--             MANDATORY IF search_in is equal to hdr             -->\n"
2224     "    <!-- check_it  : if set to true, the call is marked as failed if    -->\n"
2225     "    <!--             the regexp doesn't match.                          -->\n"
2226     "    <!--             OPTIONAL - default value : false                   -->\n"
2227     "    <!-- assign_to : contain the variable id (integer) or a list of     -->\n"
2228     "    <!--             variable id which will be used to store the        -->\n"
2229     "    <!--             result of the matching process between the regexp  -->\n"
2230     "    <!--             and the message. This variable can be re-used at   -->\n"
2231     "    <!--             a later time in the scenario using '[$n]' syntax   -->\n"
2232     "    <!--             where n is the variable id.                        -->\n"
2233     "    <!--             MANDATORY                                          -->\n"
2234     "    <action>\n"
2235     "      <ereg regexp=\"[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[:][0-9]{1,5}\" \n"
2236     "            search_in=\"msg\" \n"
2237     "            check_it=\"true\" \n"
2238     "            assign_to=\"1\"/>\n"
2239     "      <ereg regexp=\".*\" \n"
2240     "            search_in=\"hdr\" \n"
2241     "            header=\"Contact:\" \n"
2242     "            check_it=\"true\" \n"
2243     "            assign_to=\"6\"/>\n"
2244     "      <ereg regexp=\"o=([[:alnum:]]*) ([[:alnum:]]*) ([[:alnum:]]*)\"\n"
2245     "            search_in=\"msg\" \n"
2246     "            check_it=\"true\" \n"
2247     "            assign_to=\"3,4,5,8\"/>\n"
2248     "    </action>\n"
2249     "  </recv>\n"
2250     "\n"
2251     "  <send>\n"
2252     "    <![CDATA[\n"
2253     "      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2254     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2255     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2256     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2257     "      Call-ID: [call_id]\n"
2258     "      CSeq: 1 ACK\n"
2259     "      retrievedIp: [$1]\n"
2260     "      retrievedContact:[$6]\n"
2261     "      retrievedSdpOrigin:[$3]\n"
2262     "      retrievedSdpOrigin-username:[$4]\n"
2263     "      retrievedSdpOrigin-session-id:[$5]\n"
2264     "      retrievedSdpOrigin-version:[$8]\n"
2265     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2266     "      Max-Forwards: 70\n"
2267     "      Subject: Performance Test\n"
2268     "      Content-Length: 0\n"
2269     "    ]]>\n"
2270     "  </send>\n"
2271     "\n"
2272     "  <!-- This delay can be customized by the -d command-line option       -->\n"
2273     "  <!-- or by adding a 'milliseconds = \"value\"' option here.           -->\n"
2274     "  <pause milliseconds = \"1000\"/>\n"
2275     "\n"
2276     "  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2277     "  <send retrans=\"500\">\n"
2278     "    <![CDATA[\n"
2279     "\n"
2280     "      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2281     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2282     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag02[call_number]\n"
2283     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2284     "      Call-ID: [call_id]\n"
2285     "      CSeq: 2 BYE\n"
2286     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2287     "      Max-Forwards: 70\n"
2288     "      Subject: Performance Test\n"
2289     "      Content-Length: 0\n"
2290     "\n"
2291     "    ]]>\n"
2292     "  </send>\n"
2293     "\n"
2294     "  <recv response=\"200\" crlf=\"true\" rtd=\"true\">\n"
2295     "  </recv>\n"
2296     "\n"
2297     "  <!-- definition of the response time repartition table (unit is ms)   -->\n"
2298     "  <ResponseTimeRepartition value=\"1000, 1040, 1080, 1120, 1160, 1200\"/>\n"
2299     "\n"
2300     "  <!-- definition of the call length repartition table (unit is ms)     -->\n"
2301     "  <CallLengthRepartition value=\"1000, 1100, 1200, 1300, 1400\"/>\n"
2302     "\n"
2303     "</scenario>\n"
2304     "\n",
2305 
2306     /************* Default_scenario[3] ***************/
2307     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2308     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2309     "\n"
2310     "<!-- This program is free software; you can redistribute it and/or      -->\n"
2311     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
2312     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2313     "<!-- License, or (at your option) any later version.                    -->\n"
2314     "<!--                                                                    -->\n"
2315     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
2316     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
2317     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
2318     "<!-- GNU General Public License for more details.                       -->\n"
2319     "<!--                                                                    -->\n"
2320     "<!-- You should have received a copy of the GNU General Public License  -->\n"
2321     "<!-- along with this program; if not, write to the                      -->\n"
2322     "<!-- Free Software Foundation, Inc.,                                    -->\n"
2323     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
2324     "<!--                                                                    -->\n"
2325     "<!--                 3PCC - Controller - A side                         -->\n"
2326     "<!--                                                                    -->\n"
2327     "<!--             A              Controller               B              -->\n"
2328     "<!--             |(1) INVITE no SDP  |                   |              -->\n"
2329     "<!--             |<==================|                   |              -->\n"
2330     "<!--             |(2) 200 offer1     |                   |              -->\n"
2331     "<!--             |==================>|                   |              -->\n"
2332     "<!--             |                   |(3) INVITE offer1  |              -->\n"
2333     "<!--             |                   |==================>|              -->\n"
2334     "<!--             |                   |(4) 200 OK answer1 |              -->\n"
2335     "<!--             |                   |<==================|              -->\n"
2336     "<!--             |                   |(5) ACK            |              -->\n"
2337     "<!--             |                   |==================>|              -->\n"
2338     "<!--             |(6) ACK answer1    |                   |              -->\n"
2339     "<!--             |<==================|                   |              -->\n"
2340     "<!--             |(7) RTP            |                   |              -->\n"
2341     "<!--             |.......................................|              -->\n"
2342     "<!--                                                                    -->\n"
2343     "\n"
2344     "<scenario name=\"3PCC Controller - A side\">\n"
2345     "  <send retrans=\"500\">\n"
2346     "    <![CDATA[\n"
2347     "\n"
2348     "      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2349     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2350     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2351     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>\n"
2352     "      Call-ID: [call_id]\n"
2353     "      CSeq: 1 INVITE\n"
2354     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2355     "      Max-Forwards: 70\n"
2356     "      Subject: Performance Test\n"
2357     "      Content-Length: 0\n"
2358     "\n"
2359     "    ]]>\n"
2360     "  </send>\n"
2361     "\n"
2362     "  <recv response=\"100\" optional=\"true\"> </recv>\n"
2363     "  <recv response=\"180\" optional=\"true\"> </recv>\n"
2364     "  <recv response=\"183\" optional=\"true\"> </recv>\n"
2365     "  <recv response=\"200\" crlf=\"true\" start_rtd=\"true\">\n"
2366     "    <action>\n"
2367     "       <ereg regexp=\"Content-Type:.*\" \n"
2368     "             search_in=\"msg\"  \n"
2369     "             assign_to=\"1\" /> \n"
2370     "    </action>\n"
2371     "  </recv>\n"
2372     "\n"
2373     "  <sendCmd>\n"
2374     "    <![CDATA[\n"
2375     "      Call-ID: [call_id]\n"
2376     "      [$1]\n"
2377     "\n"
2378     "     ]]>\n"
2379     "  </sendCmd>\n"
2380     "  \n"
2381     "  <recvCmd>\n"
2382     "    <action>\n"
2383     "       <ereg regexp=\"Content-Type:.*\"  \n"
2384     "             search_in=\"msg\"  \n"
2385     "             assign_to=\"2\" /> \n"
2386     "    </action>\n"
2387     "  \n"
2388     "  </recvCmd>\n"
2389     "  \n"
2390     "  <send rtd=\"true\">\n"
2391     "    <![CDATA[\n"
2392     "\n"
2393     "      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2394     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2395     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2396     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2397     "      Call-ID: [call_id]\n"
2398     "      CSeq: 1 ACK\n"
2399     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2400     "      Max-Forwards: 70\n"
2401     "      Subject: Performance Test\n"
2402     "      [$2]\n"
2403     "\n"
2404     "    ]]>\n"
2405     "  </send>\n"
2406     "\n"
2407     "  <pause milliseconds=\"1000\"/>\n"
2408     "\n"
2409     "  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2410     "  <send retrans=\"500\">\n"
2411     "    <![CDATA[\n"
2412     "\n"
2413     "      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2414     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2415     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag03[call_number]\n"
2416     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2417     "      Call-ID: [call_id]\n"
2418     "      CSeq: 2 BYE\n"
2419     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2420     "      Max-Forwards: 70\n"
2421     "      Subject: Performance Test\n"
2422     "      Content-Length: 0\n"
2423     "\n"
2424     "    ]]>\n"
2425     "  </send>\n"
2426     "\n"
2427     "  <recv response=\"200\" crlf=\"true\"> </recv>\n"
2428     "\n"
2429     "</scenario>\n"
2430     "\n",
2431 
2432     /************* Default_scenario[4] ***************/
2433     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2434     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2435     "\n"
2436     "<!-- This program is free software; you can redistribute it and/or      -->\n"
2437     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
2438     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2439     "<!-- License, or (at your option) any later version.                    -->\n"
2440     "<!--                                                                    -->\n"
2441     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
2442     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
2443     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
2444     "<!-- GNU General Public License for more details.                       -->\n"
2445     "<!--                                                                    -->\n"
2446     "<!-- You should have received a copy of the GNU General Public License  -->\n"
2447     "<!-- along with this program; if not, write to the                      -->\n"
2448     "<!-- Free Software Foundation, Inc.,                                    -->\n"
2449     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
2450     "<!--                                                                    -->\n"
2451     "<!--                 3PCC - Controller - B side                         -->\n"
2452     "<!--                                                                    -->\n"
2453     "<!--             A              Controller               B              -->\n"
2454     "<!--             |(1) INVITE no SDP  |                   |              -->\n"
2455     "<!--             |<==================|                   |              -->\n"
2456     "<!--             |(2) 200 offer1     |                   |              -->\n"
2457     "<!--             |==================>|                   |              -->\n"
2458     "<!--             |                   |(3) INVITE offer1  |              -->\n"
2459     "<!--             |                   |==================>|              -->\n"
2460     "<!--             |                   |(4) 200 OK answer1 |              -->\n"
2461     "<!--             |                   |<==================|              -->\n"
2462     "<!--             |                   |(5) ACK            |              -->\n"
2463     "<!--             |                   |==================>|              -->\n"
2464     "<!--             |(6) ACK answer1    |                   |              -->\n"
2465     "<!--             |<==================|                   |              -->\n"
2466     "<!--             |(7) RTP            |                   |              -->\n"
2467     "<!--             |.......................................|              -->\n"
2468     "<!--                                                                    -->\n"
2469     "\n"
2470     "\n"
2471     "<scenario name=\"3PCC Controller - B side\">\n"
2472     "\n"
2473     "<recvCmd>\n"
2474     "  <action>\n"
2475     "       <ereg regexp=\"Content-Type:.*\"  \n"
2476     "             search_in=\"msg\"  \n"
2477     "             assign_to=\"1\" /> \n"
2478     "  </action>\n"
2479     "</recvCmd>\n"
2480     "\n"
2481     "  <send retrans=\"500\">\n"
2482     "    <![CDATA[\n"
2483     "\n"
2484     "      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2485     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2486     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2487     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>\n"
2488     "      Call-ID: [call_id]\n"
2489     "      CSeq: 1 INVITE\n"
2490     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2491     "      Max-Forwards: 70\n"
2492     "      Subject: Performance Test\n"
2493     "      [$1]\n"
2494     "\n"
2495     "     ]]>\n"
2496     "  </send>\n"
2497     "\n"
2498     "  <recv response=\"100\" optional=\"true\"> </recv>\n"
2499     "  <recv response=\"180\" optional=\"true\"> </recv>\n"
2500     "  <recv response=\"183\" optional=\"true\"> </recv>\n"
2501     "  <recv response=\"200\" crlf=\"true\">\n"
2502     "    <action>\n"
2503     "       <ereg regexp=\"Content-Type:.*\"  \n"
2504     "             search_in=\"msg\"  \n"
2505     "             assign_to=\"2\" /> \n"
2506     "    </action>\n"
2507     "  </recv>\n"
2508     "  \n"
2509     "    \n"
2510     "  <send start_rtd=\"true\">\n"
2511     "    <![CDATA[\n"
2512     "\n"
2513     "      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2514     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2515     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2516     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2517     "      Call-ID: [call_id]\n"
2518     "      CSeq: 1 ACK\n"
2519     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2520     "      Max-Forwards: 70\n"
2521     "      Subject: Performance Test\n"
2522     "      Content-Length: 0\n"
2523     "\n"
2524     "    ]]>\n"
2525     "  </send>\n"
2526     "\n"
2527     "  <sendCmd>\n"
2528     "    <![CDATA[\n"
2529     "      Call-ID: [call_id]\n"
2530     "      [$2]\n"
2531     "\n"
2532     "    ]]>\n"
2533     "  </sendCmd>\n"
2534     " \n"
2535     "  <pause milliseconds=\"1000\"/>\n"
2536     "\n"
2537     "\n"
2538     "  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
2539     "  <send retrans=\"500\" rtd=\"true\">\n"
2540     "    <![CDATA[\n"
2541     "\n"
2542     "      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
2543     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2544     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag04[call_number]\n"
2545     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
2546     "      Call-ID: [call_id]\n"
2547     "      CSeq: 2 BYE\n"
2548     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
2549     "      Max-Forwards: 70\n"
2550     "      Subject: Performance Test\n"
2551     "      Content-Length: 0\n"
2552     "\n"
2553     "    ]]>\n"
2554     "  </send>\n"
2555     "\n"
2556     "  <recv response=\"200\" crlf=\"true\">\n"
2557     "  </recv>\n"
2558     "\n"
2559     "\n"
2560     "</scenario>\n"
2561     "\n",
2562 
2563     /************* Default_scenario[5] ***************/
2564     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2565     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2566     "\n"
2567     "<!-- This program is free software; you can redistribute it and/or      -->\n"
2568     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
2569     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2570     "<!-- License, or (at your option) any later version.                    -->\n"
2571     "<!--                                                                    -->\n"
2572     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
2573     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
2574     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
2575     "<!-- GNU General Public License for more details.                       -->\n"
2576     "<!--                                                                    -->\n"
2577     "<!-- You should have received a copy of the GNU General Public License  -->\n"
2578     "<!-- along with this program; if not, write to the                      -->\n"
2579     "<!-- Free Software Foundation, Inc.,                                    -->\n"
2580     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
2581     "<!--                                                                    -->\n"
2582     "<!--                 3PCC - A side emulator                             -->\n"
2583     "<!--                                                                    -->\n"
2584     "<!--             A              Controller               B              -->\n"
2585     "<!--             |(1) INVITE no SDP  |                   |              -->\n"
2586     "<!--             |<==================|                   |              -->\n"
2587     "<!--             |(2) 200 offer1     |                   |              -->\n"
2588     "<!--             |==================>|                   |              -->\n"
2589     "<!--             |                   |(3) INVITE offer1  |              -->\n"
2590     "<!--             |                   |==================>|              -->\n"
2591     "<!--             |                   |(4) 200 OK answer1 |              -->\n"
2592     "<!--             |                   |<==================|              -->\n"
2593     "<!--             |                   |(5) ACK            |              -->\n"
2594     "<!--             |                   |==================>|              -->\n"
2595     "<!--             |(6) ACK answer1    |                   |              -->\n"
2596     "<!--             |<==================|                   |              -->\n"
2597     "<!--             |(7) RTP            |                   |              -->\n"
2598     "<!--             |.......................................|              -->\n"
2599     "<!--                                                                    -->\n"
2600     "\n"
2601     "\n"
2602     "<scenario name=\"3PCC A side\">\n"
2603     "  <recv request=\"INVITE\" crlf=\"true\">\n"
2604     "  </recv>\n"
2605     "\n"
2606     "  <send>\n"
2607     "    <![CDATA[\n"
2608     "\n"
2609     "      SIP/2.0 200 OK\n"
2610     "      [last_Via:]\n"
2611     "      [last_From:]\n"
2612     "      [last_To:];tag=[pid]SIPpTag05[call_number]\n"
2613     "      [last_Call-ID:]\n"
2614     "      [last_CSeq:]\n"
2615     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2616     "      Content-Type: application/sdp\n"
2617     "      Content-Length: [len]\n"
2618     "\n"
2619     "      v=0\n"
2620     "      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2621     "      s=-\n"
2622     "      c=IN IP[media_ip_type] [media_ip]\n"
2623     "      t=0 0\n"
2624     "      m=audio [media_port] RTP/AVP 0\n"
2625     "      a=rtpmap:0 PCMU/8000\n"
2626     "\n"
2627     "    ]]>\n"
2628     "  </send>\n"
2629     "\n"
2630     "  <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
2631     "\n"
2632     "  <!-- RTP flow starts from here! -->\n"
2633     "\n"
2634     "  <recv request=\"BYE\" crlf=\"true\"> </recv>\n"
2635     "\n"
2636     "  <send>\n"
2637     "    <![CDATA[\n"
2638     "\n"
2639     "      SIP/2.0 200 OK\n"
2640     "      [last_Via:]\n"
2641     "      [last_From:]\n"
2642     "      [last_To:]\n"
2643     "      [last_Call-ID:]\n"
2644     "      [last_CSeq:]\n"
2645     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2646     "      Content-Length: 0\n"
2647     "\n"
2648     "    ]]>\n"
2649     "  </send>\n"
2650     "\n"
2651     "  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
2652     "  <!-- able to retransmit it if we receive the BYE again.               -->\n"
2653     "  <timewait milliseconds=\"2000\"/>\n"
2654     "\n"
2655     "</scenario>\n"
2656     "\n",
2657 
2658     /************* Default_scenario[6] ***************/
2659     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2660     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2661     "\n"
2662     "<!-- This program is free software; you can redistribute it and/or      -->\n"
2663     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
2664     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2665     "<!-- License, or (at your option) any later version.                    -->\n"
2666     "<!--                                                                    -->\n"
2667     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
2668     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
2669     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
2670     "<!-- GNU General Public License for more details.                       -->\n"
2671     "<!--                                                                    -->\n"
2672     "<!-- You should have received a copy of the GNU General Public License  -->\n"
2673     "<!-- along with this program; if not, write to the                      -->\n"
2674     "<!-- Free Software Foundation, Inc.,                                    -->\n"
2675     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
2676     "<!--                                                                    -->\n"
2677     "<!--                 3PCC - B side emulator                             -->\n"
2678     "<!--                                                                    -->\n"
2679     "<!--             A              Controller               B              -->\n"
2680     "<!--             |(1) INVITE no SDP  |                   |              -->\n"
2681     "<!--             |<==================|                   |              -->\n"
2682     "<!--             |(2) 200 offer1     |                   |              -->\n"
2683     "<!--             |==================>|                   |              -->\n"
2684     "<!--             |                   |(3) INVITE offer1  |              -->\n"
2685     "<!--             |                   |==================>|              -->\n"
2686     "<!--             |                   |(4) 200 OK answer1 |              -->\n"
2687     "<!--             |                   |<==================|              -->\n"
2688     "<!--             |                   |(5) ACK            |              -->\n"
2689     "<!--             |                   |==================>|              -->\n"
2690     "<!--             |(6) ACK answer1    |                   |              -->\n"
2691     "<!--             |<==================|                   |              -->\n"
2692     "<!--             |(7) RTP            |                   |              -->\n"
2693     "<!--             |.......................................|              -->\n"
2694     "<!--                                                                    -->\n"
2695     "\n"
2696     "\n"
2697     "\n"
2698     "<scenario name=\"3PCC B side\">\n"
2699     "  <recv request=\"INVITE\" crlf=\"true\"> </recv>\n"
2700     "\n"
2701     "  <send>\n"
2702     "    <![CDATA[\n"
2703     "\n"
2704     "      SIP/2.0 200 OK\n"
2705     "      [last_Via:]\n"
2706     "      [last_From:]\n"
2707     "      [last_To:];tag=[pid]SIPpTag06[call_number]\n"
2708     "      [last_Call-ID:]\n"
2709     "      [last_CSeq:]\n"
2710     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2711     "      Content-Type: application/sdp\n"
2712     "      Content-Length: [len]\n"
2713     "\n"
2714     "      v=0\n"
2715     "      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2716     "      s=-\n"
2717     "      c=IN IP[media_ip_type] [media_ip]\n"
2718     "      t=0 0\n"
2719     "      m=audio [media_port] RTP/AVP 0\n"
2720     "      a=rtpmap:0 PCMU/8000\n"
2721     "\n"
2722     "    ]]>\n"
2723     "  </send>\n"
2724     "\n"
2725     "  <recv request=\"ACK\" rtd=\"true\" crlf=\"true\"> </recv>\n"
2726     "\n"
2727     "  <!-- RTP flow starts from here! -->\n"
2728     "\n"
2729     "  <recv request=\"BYE\"> </recv>\n"
2730     "\n"
2731     "  <send>\n"
2732     "    <![CDATA[\n"
2733     "\n"
2734     "      SIP/2.0 200 OK\n"
2735     "      [last_Via:]\n"
2736     "      [last_From:]\n"
2737     "      [last_To:]\n"
2738     "      [last_Call-ID:]\n"
2739     "      [last_CSeq:]\n"
2740     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2741     "      Content-Length: 0\n"
2742     "\n"
2743     "    ]]>\n"
2744     "  </send>\n"
2745     "\n"
2746     "  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
2747     "  <!-- able to retransmit it if we receive the BYE again.               -->\n"
2748     "  <timewait milliseconds=\"2000\"/>\n"
2749     "\n"
2750     "</scenario>\n",
2751 
2752     /************* Default_scenario[7] ***************/
2753     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2754     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2755     "\n"
2756     "<!-- This program is free software; you can redistribute it and/or      -->\n"
2757     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
2758     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2759     "<!-- License, or (at your option) any later version.                    -->\n"
2760     "<!--                                                                    -->\n"
2761     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
2762     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
2763     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
2764     "<!-- GNU General Public License for more details.                       -->\n"
2765     "<!--                                                                    -->\n"
2766     "<!-- You should have received a copy of the GNU General Public License  -->\n"
2767     "<!-- along with this program; if not, write to the                      -->\n"
2768     "<!-- Free Software Foundation, Inc.,                                    -->\n"
2769     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
2770     "<!--                                                                    -->\n"
2771     "<!--                 Sipp default 'branchc' scenario.                   -->\n"
2772     "<!--                                                                    -->\n"
2773     "\n"
2774     "<scenario name=\"branch_client\">\n"
2775     "  <send retrans=\"500\">\n"
2776     "    <![CDATA[\n"
2777     "\n"
2778     "      REGISTER sip:CA.cym.com SIP/2.0\n"
2779     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2780     "      From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07[call_number]\n"
2781     "      To: ua1 <sip:ua1@nnl.cym:[local_port]>\n"
2782     "      Call-ID: [call_id]\n"
2783     "      CSeq: 1 REGISTER\n"
2784     "      Contact: sip:ua1@[local_ip]:[local_port]\n"
2785     "      Content-Length: 0\n"
2786     "      Expires: 300\n"
2787     "\n"
2788     "    ]]>\n"
2789     "  </send>\n"
2790     "\n"
2791     "  <!-- simple case - just jump over a line   -->\n"
2792     "  <recv response=\"200\" rtd=\"true\" next=\"5\">\n"
2793     "  </recv>\n"
2794     "\n"
2795     "  <recv response=\"200\">\n"
2796     "  </recv>\n"
2797     "\n"
2798     "  <label id=\"5\"/>\n"
2799     "\n"
2800     "  <send retrans=\"500\">\n"
2801     "    <![CDATA[\n"
2802     "\n"
2803     "      INVITE sip:ua2@CA.cym.com SIP/2.0\n"
2804     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2805     "      From: ua[call_number] <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2806     "      To: ua2 <sip:ua2@nnl.cym:[remote_port]>\n"
2807     "      Call-ID: [call_id]\n"
2808     "      CSeq: 1 INVITE\n"
2809     "      Contact: sip:ua1@[local_ip]:[local_port]\n"
2810     "      Max-Forwards: 70\n"
2811     "      Subject: Performance Test\n"
2812     "      Content-Type: application/sdp\n"
2813     "      Content-Length: [len]\n"
2814     "\n"
2815     "      v=0\n"
2816     "      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
2817     "      s=-\n"
2818     "      c=IN IP[media_ip_type] [media_ip]\n"
2819     "      t=0 0\n"
2820     "      m=audio [media_port] RTP/AVP 0\n"
2821     "      a=rtpmap:0 PCMU/8000\n"
2822     "\n"
2823     "    ]]>\n"
2824     "  </send>\n"
2825     "\n"
2826     "  <recv response=\"100\" optional=\"true\">\n"
2827     "  </recv>\n"
2828     "\n"
2829     "  <recv response=\"180\" optional=\"true\">\n"
2830     "  </recv>\n"
2831     "\n"
2832     "  <recv response=\"183\" optional=\"true\">\n"
2833     "  </recv>\n"
2834     "\n"
2835     "  <!-- Do something different on an optional receive   -->\n"
2836     "  <recv response=\"403\" optional=\"true\" next=\"1\">\n"
2837     "  </recv>\n"
2838     "\n"
2839     "  <recv response=\"200\">\n"
2840     "    <action>\n"
2841     "      <ereg regexp=\"ua25\"\n"
2842     "            search_in=\"hdr\"\n"
2843     "            header=\"From: \"\n"
2844     "            assign_to=\"8\"/>\n"
2845     "    </action>\n"
2846     "  </recv>\n"
2847     "\n"
2848     "  <!-- set variable 8 above on 25th call, send the ACK but skip the pause for it   -->\n"
2849     "  <send next=\"1\" test=\"8\">\n"
2850     "    <![CDATA[\n"
2851     "\n"
2852     "      ACK sip:ua2@CA.cym.com SIP/2.0\n"
2853     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2854     "      From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2855     "      To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
2856     "      Call-ID: [call_id]\n"
2857     "      CSeq: 1 ACK\n"
2858     "      Contact: sip:ua1@[local_ip]:[local_port]\n"
2859     "      Max-Forwards: 70\n"
2860     "      Subject: Performance Test\n"
2861     "      Content-Length: 0\n"
2862     "\n"
2863     "    ]]>\n"
2864     "  </send>\n"
2865     "\n"
2866     "  <pause milliseconds=\"5000\"/>\n"
2867     "\n"
2868     "  <label id=\"1\"/>\n"
2869     "\n"
2870     "  <send retrans=\"500\">\n"
2871     "    <![CDATA[\n"
2872     "\n"
2873     "      BYE sip:ua2@CA.cym.com SIP/2.0\n"
2874     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
2875     "      From: ua1 <sip:ua1@nnl.cym:[local_port]>;tag=[pid]SIPpTag07b[call_number]\n"
2876     "      To: ua2 <sip:ua2@nnl.cym:[remote_port]>[peer_tag_param]\n"
2877     "      Call-ID: [call_id]\n"
2878     "      CSeq: 2 BYE\n"
2879     "      Contact: sip:ua1@[local_ip]:[local_port]\n"
2880     "      Max-Forwards: 70\n"
2881     "      Subject: Performance Test\n"
2882     "      Content-Length: 0\n"
2883     "\n"
2884     "    ]]>\n"
2885     "  </send>\n"
2886     "\n"
2887     "  <recv response=\"200\" crlf=\"true\">\n"
2888     "  </recv>\n"
2889     "\n"
2890     "  <pause milliseconds=\"4000\"/>\n"
2891     "\n"
2892     "  <!-- definition of the response time repartition table (unit is ms)   -->\n"
2893     "  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
2894     "\n"
2895     "  <!-- definition of the call length repartition table (unit is ms)     -->\n"
2896     "  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
2897     "\n"
2898     "</scenario>\n"
2899     "\n",
2900 
2901     /************* Default_scenario[8] ***************/
2902     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
2903     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
2904     "\n"
2905     "<!-- This program is free software; you can redistribute it and/or      -->\n"
2906     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
2907     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
2908     "<!-- License, or (at your option) any later version.                    -->\n"
2909     "<!--                                                                    -->\n"
2910     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
2911     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
2912     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
2913     "<!-- GNU General Public License for more details.                       -->\n"
2914     "<!--                                                                    -->\n"
2915     "<!-- You should have received a copy of the GNU General Public License  -->\n"
2916     "<!-- along with this program; if not, write to the                      -->\n"
2917     "<!-- Free Software Foundation, Inc.,                                    -->\n"
2918     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
2919     "<!--                                                                    -->\n"
2920     "<!--                 Sipp default 'branchs' scenario.                   -->\n"
2921     "<!--                                                                    -->\n"
2922     "\n"
2923     "<scenario name=\"branch_server\">\n"
2924     "  <recv request=\"REGISTER\">\n"
2925     "  </recv>\n"
2926     "\n"
2927     "  <send>\n"
2928     "    <![CDATA[\n"
2929     "\n"
2930     "      SIP/2.0 200 OK\n"
2931     "      [last_Via:]\n"
2932     "      [last_From:]\n"
2933     "      [last_To:];tag=[pid]SIPpTag08[call_number]\n"
2934     "      [last_Call-ID:]\n"
2935     "      [last_CSeq:]\n"
2936     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2937     "      Content-Length: 0\n"
2938     "      Expires: 300\n"
2939     "\n"
2940     "    ]]>\n"
2941     "  </send>\n"
2942     "\n"
2943     "  <!-- Set variable 3 if the ua is of the form ua2... -->\n"
2944     "  <recv request=\"INVITE\" crlf=\"true\">\n"
2945     "    <action>\n"
2946     "      <ereg regexp=\"ua2\"\n"
2947     "            search_in=\"hdr\"\n"
2948     "            header=\"From: \"\n"
2949     "            assign_to=\"3\"/>\n"
2950     "    </action>\n"
2951     "  </recv>\n"
2952     "\n"
2953     "  <!-- send 180 then trying if variable 3 is set -->\n"
2954     "  <send next=\"1\" test=\"3\">\n"
2955     "    <![CDATA[\n"
2956     "\n"
2957     "      SIP/2.0 180 Ringing\n"
2958     "      [last_Via:]\n"
2959     "      [last_From:]\n"
2960     "      [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2961     "      [last_Call-ID:]\n"
2962     "      [last_CSeq:]\n"
2963     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2964     "      Content-Length: 0\n"
2965     "\n"
2966     "    ]]>\n"
2967     "  </send>\n"
2968     "\n"
2969     "  <!-- if not, send a 403 error then skip to wait for a BYE -->\n"
2970     "  <send next=\"2\">\n"
2971     "    <![CDATA[\n"
2972     "\n"
2973     "      SIP/2.0 403 Error\n"
2974     "      [last_Via:]\n"
2975     "      [last_From:]\n"
2976     "      [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2977     "      [last_Call-ID:]\n"
2978     "      [last_CSeq:]\n"
2979     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2980     "      Content-Length: 0\n"
2981     "\n"
2982     "    ]]>\n"
2983     "  </send>\n"
2984     "\n"
2985     "  <label id=\"1\"/>\n"
2986     "\n"
2987     "  <send>\n"
2988     "    <![CDATA[\n"
2989     "\n"
2990     "      SIP/2.0 100 Trying\n"
2991     "      [last_Via:]\n"
2992     "      [last_From:]\n"
2993     "      [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
2994     "      [last_Call-ID:]\n"
2995     "      [last_CSeq:]\n"
2996     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
2997     "      Content-Length: 0\n"
2998     "\n"
2999     "    ]]>\n"
3000     "  </send>\n"
3001     "\n"
3002     "  <send retrans=\"500\">\n"
3003     "    <![CDATA[\n"
3004     "\n"
3005     "      SIP/2.0 200 OK\n"
3006     "      [last_Via:]\n"
3007     "      [last_From:]\n"
3008     "      [last_To:];tag=[pid]SIPpTag08b[call_number]\n"
3009     "      [last_Call-ID:]\n"
3010     "      [last_CSeq:]\n"
3011     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
3012     "      Content-Type: application/sdp\n"
3013     "      Content-Length: [len]\n"
3014     "\n"
3015     "      v=0\n"
3016     "      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
3017     "      s=-\n"
3018     "      c=IN IP[media_ip_type] [media_ip]\n"
3019     "      t=0 0\n"
3020     "      m=audio [media_port] RTP/AVP 0\n"
3021     "      a=rtpmap:0 PCMU/8000\n"
3022     "\n"
3023     "    ]]>\n"
3024     "  </send>\n"
3025     "\n"
3026     "  <recv request=\"ACK\"\n"
3027     "        optional=\"true\"\n"
3028     "        rtd=\"true\"\n"
3029     "        crlf=\"true\">\n"
3030     "  </recv>\n"
3031     "\n"
3032     "  <label id=\"2\"/>\n"
3033     "\n"
3034     "  <recv request=\"BYE\">\n"
3035     "  </recv>\n"
3036     "\n"
3037     "  <send>\n"
3038     "    <![CDATA[\n"
3039     "\n"
3040     "      SIP/2.0 200 OK\n"
3041     "      [last_Via:]\n"
3042     "      [last_From:]\n"
3043     "      [last_To:]\n"
3044     "      [last_Call-ID:]\n"
3045     "      [last_CSeq:]\n"
3046     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
3047     "      Content-Length: 0\n"
3048     "\n"
3049     "    ]]>\n"
3050     "  </send>\n"
3051     "\n"
3052     "  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
3053     "  <!-- able to retransmit it if we receive the BYE again.               -->\n"
3054     "  <timewait milliseconds=\"4000\"/>\n"
3055     "\n"
3056     "  <!-- Definition of the response time repartition table (unit is ms)   -->\n"
3057     "  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3058     "\n"
3059     "  <!-- Definition of the call length repartition table (unit is ms)     -->\n"
3060     "  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3061     "\n"
3062     "</scenario>\n"
3063     "\n",
3064 
3065     /* Although this scenario will not work without pcap play enabled, there is no
3066      * harm in including it in the binary anyway, because the user could have
3067      * dumped it and passed it with -sf. */
3068 
3069     /************* Default_scenario[9] ***************/
3070     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
3071     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
3072     "\n"
3073     "<!-- This program is free software; you can redistribute it and/or      -->\n"
3074     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
3075     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
3076     "<!-- License, or (at your option) any later version.                    -->\n"
3077     "<!--                                                                    -->\n"
3078     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
3079     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
3080     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
3081     "<!-- GNU General Public License for more details.                       -->\n"
3082     "<!--                                                                    -->\n"
3083     "<!-- You should have received a copy of the GNU General Public License  -->\n"
3084     "<!-- along with this program; if not, write to the                      -->\n"
3085     "<!-- Free Software Foundation, Inc.,                                    -->\n"
3086     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
3087     "<!--                                                                    -->\n"
3088     "<!--                 Sipp 'uac' scenario with pcap (rtp) play           -->\n"
3089     "<!--                                                                    -->\n"
3090     "\n"
3091     "<scenario name=\"UAC with media\">\n"
3092     "  <!-- In client mode (sipp placing calls), the Call-ID MUST be         -->\n"
3093     "  <!-- generated by sipp. To do so, use [call_id] keyword.                -->\n"
3094     "  <send retrans=\"500\">\n"
3095     "    <![CDATA[\n"
3096     "\n"
3097     "      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3098     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3099     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3100     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>\n"
3101     "      Call-ID: [call_id]\n"
3102     "      CSeq: 1 INVITE\n"
3103     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
3104     "      Max-Forwards: 70\n"
3105     "      Subject: Performance Test\n"
3106     "      Content-Type: application/sdp\n"
3107     "      Content-Length: [len]\n"
3108     "\n"
3109     "      v=0\n"
3110     "      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]\n"
3111     "      s=-\n"
3112     "      c=IN IP[local_ip_type] [local_ip]\n"
3113     "      t=0 0\n"
3114     "      m=audio [auto_media_port] RTP/AVP 8 101\n"
3115     "      a=rtpmap:8 PCMA/8000\n"
3116     "      a=rtpmap:101 telephone-event/8000\n"
3117     "      a=fmtp:101 0-11,16\n"
3118     "\n"
3119     "    ]]>\n"
3120     "  </send>\n"
3121     "\n"
3122     "  <recv response=\"100\" optional=\"true\">\n"
3123     "  </recv>\n"
3124     "\n"
3125     "  <recv response=\"180\" optional=\"true\">\n"
3126     "  </recv>\n"
3127     "\n"
3128     "  <!-- By adding rrs=\"true\" (Record Route Sets), the route sets         -->\n"
3129     "  <!-- are saved and used for following messages sent. Useful to test   -->\n"
3130     "  <!-- against stateful SIP proxies/B2BUAs.                             -->\n"
3131     "  <recv response=\"200\" rtd=\"true\" crlf=\"true\">\n"
3132     "  </recv>\n"
3133     "\n"
3134     "  <!-- Packet lost can be simulated in any send/recv message by         -->\n"
3135     "  <!-- by adding the 'lost = \"10\"'. Value can be [1-100] percent.       -->\n"
3136     "  <send>\n"
3137     "    <![CDATA[\n"
3138     "\n"
3139     "      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3140     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3141     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3142     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
3143     "      Call-ID: [call_id]\n"
3144     "      CSeq: 1 ACK\n"
3145     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
3146     "      Max-Forwards: 70\n"
3147     "      Subject: Performance Test\n"
3148     "      Content-Length: 0\n"
3149     "\n"
3150     "    ]]>\n"
3151     "  </send>\n"
3152     "\n"
3153     "  <!-- Play a pre-recorded PCAP file (RTP stream)                       -->\n"
3154     "  <nop>\n"
3155     "    <action>\n"
3156     "      <exec play_pcap_audio=\"/usr/local/share/sipp/pcap/g711a.pcap\"/>\n"
3157     "    </action>\n"
3158     "  </nop>\n"
3159     "\n"
3160     "  <!-- Pause 8 seconds, which is approximately the duration of the      -->\n"
3161     "  <!-- PCAP file                                                        -->\n"
3162     "  <pause milliseconds=\"8000\"/>\n"
3163     "\n"
3164     "  <!-- Play an out of band DTMF '1'                                     -->\n"
3165     "  <nop>\n"
3166     "    <action>\n"
3167     "      <exec play_pcap_audio=\"/usr/local/share/sipp/pcap/dtmf_2833_1.pcap\"/>\n"
3168     "    </action>\n"
3169     "  </nop>\n"
3170     "\n"
3171     "  <pause milliseconds=\"1000\"/>\n"
3172     "\n"
3173     "  <!-- The 'crlf' option inserts a blank line in the statistics report. -->\n"
3174     "  <send retrans=\"500\">\n"
3175     "    <![CDATA[\n"
3176     "\n"
3177     "      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"
3178     "      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]\n"
3179     "      From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag09[call_number]\n"
3180     "      To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n"
3181     "      Call-ID: [call_id]\n"
3182     "      CSeq: 2 BYE\n"
3183     "      Contact: sip:sipp@[local_ip]:[local_port]\n"
3184     "      Max-Forwards: 70\n"
3185     "      Subject: Performance Test\n"
3186     "      Content-Length: 0\n"
3187     "\n"
3188     "    ]]>\n"
3189     "  </send>\n"
3190     "\n"
3191     "  <recv response=\"200\" crlf=\"true\">\n"
3192     "  </recv>\n"
3193     "\n"
3194     "  <!-- definition of the response time repartition table (unit is ms)   -->\n"
3195     "  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3196     "\n"
3197     "  <!-- definition of the call length repartition table (unit is ms)     -->\n"
3198     "  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3199     "\n"
3200     "</scenario>\n"
3201     "\n",
3202     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
3203     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
3204     "\n"
3205     "<!-- This program is free software; you can redistribute it and/or      -->\n"
3206     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
3207     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
3208     "<!-- License, or (at your option) any later version.                    -->\n"
3209     "<!--                                                                    -->\n"
3210     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
3211     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
3212     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
3213     "<!-- GNU General Public License for more details.                       -->\n"
3214     "<!--                                                                    -->\n"
3215     "<!-- You should have received a copy of the GNU General Public License  -->\n"
3216     "<!-- along with this program; if not, write to the                      -->\n"
3217     "<!-- Free Software Foundation, Inc.,                                    -->\n"
3218     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
3219     "<!--                                                                    -->\n"
3220     "<!--                 Sipp default 'uas' scenario.                       -->\n"
3221     "<!--                                                                    -->\n"
3222     "\n"
3223     "<scenario name=\"Out-of-call UAS\">\n"
3224     "  <recv request=\".*\" regexp_match=\"true\" />\n"
3225     "\n"
3226     "  <send>\n"
3227     "    <![CDATA[\n"
3228     "      SIP/2.0 200 OK\n"
3229     "      [last_Via:]\n"
3230     "      [last_From:]\n"
3231     "      [last_To:]\n"
3232     "      [last_Call-ID:]\n"
3233     "      [last_CSeq:]\n"
3234     "      Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"
3235     "      Content-Length: 0\n"
3236     "\n"
3237     "    ]]>\n"
3238     "  </send>\n"
3239     "\n"
3240     "  <!-- Keep the call open for a while in case the 200 is lost to be     -->\n"
3241     "  <!-- able to retransmit it if we receive the BYE again.               -->\n"
3242     "  <timewait milliseconds=\"4000\"/>\n"
3243     "\n"
3244     "\n"
3245     "  <!-- definition of the response time repartition table (unit is ms)   -->\n"
3246     "  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3247     "\n"
3248     "  <!-- definition of the call length repartition table (unit is ms)     -->\n"
3249     "  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3250     "\n"
3251     "</scenario>\n",
3252     "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
3253     "<!DOCTYPE scenario SYSTEM \"sipp.dtd\">\n"
3254     "\n"
3255     "<!-- This program is free software; you can redistribute it and/or      -->\n"
3256     "<!-- modify it under the terms of the GNU General Public License as     -->\n"
3257     "<!-- published by the Free Software Foundation; either version 2 of the -->\n"
3258     "<!-- License, or (at your option) any later version.                    -->\n"
3259     "<!--                                                                    -->\n"
3260     "<!-- This program is distributed in the hope that it will be useful,    -->\n"
3261     "<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->\n"
3262     "<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->\n"
3263     "<!-- GNU General Public License for more details.                       -->\n"
3264     "<!--                                                                    -->\n"
3265     "<!-- You should have received a copy of the GNU General Public License  -->\n"
3266     "<!-- along with this program; if not, write to the                      -->\n"
3267     "<!-- Free Software Foundation, Inc.,                                    -->\n"
3268     "<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->\n"
3269     "<!--                                                                    -->\n"
3270     "<!--                 Sipp default 'uas' scenario.                       -->\n"
3271     "<!--                                                                    -->\n"
3272     "\n"
3273     "<scenario name=\"Out-of-call UAS\">\n"
3274     "  <recv request=\"DUMMY\" />\n"
3275     "\n"
3276     "  <!-- definition of the response time repartition table (unit is ms)   -->\n"
3277     "  <ResponseTimeRepartition value=\"10, 20, 30, 40, 50, 100, 150, 200\"/>\n"
3278     "\n"
3279     "  <!-- definition of the call length repartition table (unit is ms)     -->\n"
3280     "  <CallLengthRepartition value=\"10, 50, 100, 500, 1000, 5000, 10000\"/>\n"
3281     "\n"
3282     "</scenario>\n",
3283 };
3284