2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008 Herbert Haas
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
26 "| RTP type: Send Real Time Protocol packets.\n" \
28 "| This mode is solely intended to conduct delay, drop, and jitter measurements in\n" \
29 "| Voice (Video) over IP networks. You will typically initiate another Mausezahn\n" \
30 "| instance on the destination host, which will perform the measurements or even\n" \
31 "| 'bounce back' the packets for Round Trip Time (RTT) measurements.\n" \
33 "| When the delay parameter is not specified, the default (inter-packet) delay is\n" \
34 "| set to 20 msec. You must specify the destination host using the -B option.\n" \
35 "| The default destination port is (UDP) 30000 but can be overridden (dp parameter).\n" \
36 "| You do not need to specify the count option (-c), because 'infinite' (0) is assumed.\n" \
38 "| You can specify these additional GENERAL options:\n" \
40 "| -c <count> ..... use this packet count value instead of infinity.\n" \
41 "| -d <delay> ..... use this delay value instead of the defaul. Per default\n" \
42 "| the units are microseconds but you can also use msec or sec\n" \
44 "| You can specify these additional UDP/RTP-specific arguments:\n" \
46 "| dp = <1-65535> ..... use this UDP destination port instead of 30,000.\n" \
47 "| sp = <1-65535> ..... use this UDP source port instead of random.\n" \
48 "| ssrc = XX:XX:XX:XX ... use this hex sequence as stream identifier\n" \
49 "| (=SSRC, required for multiple concurrent measurements)\n" \
50 "| codec ..... simulate G.711 codec (other will follow).\n" \
51 "| pld = <1..1000> ....... create specified payload size (default=160 bytes, which results\n" \
52 "| in a total datagram length of 180 bytes, considering the UDP and\n" \
53 "| RTP header lengths (8 and 12 bytes, respectively).\n" \
55 "| Additional help: enter 'mz -T rtp help'\n" \
59 int create_rtp_packet(void)
61 u_int8_t byte1
, byte2
;
63 u_int8_t ssrc
[4] = {0,0,0,0} ;
66 char argval
[MAX_PAYLOAD_SIZE
];
67 unsigned int rtp_payload_size
=160;
68 struct mz_timestamp ts
;
70 if ( (getarg(tx
.arg_string
,"help", NULL
)==1) && (mode
==RTP
) ) {
73 cli_print(gcli
, "%s", MZ_RTP_HELP
);
87 if (getarg(tx
.arg_string
,"pld", argval
)==1) {
88 rtp_payload_size
= (unsigned int) str2int(argval
);
91 if (getarg(tx
.arg_string
,"codec", argval
)==1) {
95 if (getarg(tx
.arg_string
,"ssrc", argval
)==1) {
96 ssrc_s
= str2hex(argval
, ssrc
, 4);
98 fprintf(stderr
, " mz/rtp: invalid ssrc!\n");
103 // TODO: Optional arguments for RTP
110 // +--+--+--+--+--+--+--+--+
111 // | ver | P| X| CSRC Count|
112 // +--+--+--+--+--+--+--+--+
114 // Default: ver=2, Padding=0, Extension_Header=1, CSRC_Count=0 => 10 0 1 0000 = 0x90
120 // +--+--+--+--+--+--+--+--+
121 // | M| Payload Type |
122 // +--+--+--+--+--+--+--+--+
124 // Marker=0, Payload Type=0 (or 8 alternatively)
130 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
131 // | Sequence Number |
132 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
138 // Timestamp /* done below */
144 // Synchronization Source Identifier
147 if (ssrc_s
==0) str2hex("ca:fe:fe:ed", ssrc
, 4);
151 // CSRC - Contributing Source Identifiers (optional, only used by mixers)
153 // csrc = 0x00000000;
157 // Header Extension (optional) NOT USED HERE!
160 // !!! Thus payload begins with index 16 in a C array !!!
162 // ------------ Now combine all fields: ----------------
163 tx
.udp_payload
[0] = byte1
;
164 tx
.udp_payload
[1] = byte2
;
166 ptr
= (u_int8_t
*) &seqnr
;
167 tx
.udp_payload
[2] = *(ptr
+1);
168 tx
.udp_payload
[3] = *ptr
;
170 // TIMESTAMP: will be linearly increased, e.g. using 20msec G.711: 0, 160, 320, ...
171 tx
.udp_payload
[4] = 0x00;
172 tx
.udp_payload
[5] = 0x00;
173 tx
.udp_payload
[6] = 0x00;
174 tx
.udp_payload
[7] = 0x00;
176 tx
.udp_payload
[8] = ssrc
[0];
177 tx
.udp_payload
[9] = ssrc
[1];
178 tx
.udp_payload
[10] = ssrc
[2];
179 tx
.udp_payload
[11] = ssrc
[3];
182 ptr = (u_int8_t*) &csrc;
183 tx.udp_payload[12] = *(ptr+3);
184 tx.udp_payload[13] = *(ptr+2);
185 tx.udp_payload[14] = *(ptr+1);
186 tx.udp_payload[15] = *ptr;
189 // Add the NEW Mausezahn extension header (see mops_ext_rtp.c)
190 tx
.udp_payload
[12] = 0xca; // identifier
191 tx
.udp_payload
[13] = 0xca;
192 tx
.udp_payload
[14] = 0x00;
193 tx
.udp_payload
[15] = 0x04; // length
194 getcurtime(&ts
); // Now add TX timestamp:
195 mops_hton4 ((u_int32_t
*) &ts
.sec
, &tx
.udp_payload
[16]);
196 mops_hton4 ((u_int32_t
*) &ts
.nsec
, &tx
.udp_payload
[20]);
197 // NOTE: The remaining 8 bytes of this extension header are set to zero
198 // via the following code.
200 memset(&tx
.udp_payload
[24], 0x00, (rtp_payload_size
-12)); // payload (considering our 8 byte timestamp)
201 tx
.udp_payload_s
= 12 + rtp_payload_size
; // the latter ist the payload size
203 // ---------- now hand over to UDP -----------------
208 tx
.udp_len
= 8 + tx
.udp_payload_s
;