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" \
60 int create_rtp_packet(void)
62 u_int8_t byte1
, byte2
;
64 u_int8_t ssrc
[4] = {0,0,0,0} ;
67 char argval
[MAX_PAYLOAD_SIZE
];
68 unsigned int rtp_payload_size
=160;
69 struct mz_timestamp ts
;
71 if ( (getarg(tx
.arg_string
,"help", NULL
)==1) && (mode
==RTP
) ) {
74 cli_print(gcli
, "%s", MZ_RTP_HELP
);
88 if (getarg(tx
.arg_string
,"pld", argval
)==1) {
89 rtp_payload_size
= (unsigned int) str2int(argval
);
92 if (getarg(tx
.arg_string
,"codec", argval
)==1) {
96 if (getarg(tx
.arg_string
,"ssrc", argval
)==1) {
97 ssrc_s
= str2hex(argval
, ssrc
, 4);
99 fprintf(stderr
, " mz/rtp: invalid ssrc!\n");
104 // TODO: Optional arguments for RTP
111 // +--+--+--+--+--+--+--+--+
112 // | ver | P| X| CSRC Count|
113 // +--+--+--+--+--+--+--+--+
115 // Default: ver=2, Padding=0, Extension_Header=1, CSRC_Count=0 => 10 0 1 0000 = 0x90
121 // +--+--+--+--+--+--+--+--+
122 // | M| Payload Type |
123 // +--+--+--+--+--+--+--+--+
125 // Marker=0, Payload Type=0 (or 8 alternatively)
131 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
132 // | Sequence Number |
133 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
139 // Timestamp /* done below */
145 // Synchronization Source Identifier
148 if (ssrc_s
==0) str2hex("ca:fe:fe:ed", ssrc
, 4);
152 // CSRC - Contributing Source Identifiers (optional, only used by mixers)
154 // csrc = 0x00000000;
158 // Header Extension (optional) NOT USED HERE!
161 // !!! Thus payload begins with index 16 in a C array !!!
163 // ------------ Now combine all fields: ----------------
164 tx
.udp_payload
[0] = byte1
;
165 tx
.udp_payload
[1] = byte2
;
167 ptr
= (u_int8_t
*) &seqnr
;
168 tx
.udp_payload
[2] = *(ptr
+1);
169 tx
.udp_payload
[3] = *ptr
;
171 // TIMESTAMP: will be linearly increased, e.g. using 20msec G.711: 0, 160, 320, ...
172 tx
.udp_payload
[4] = 0x00;
173 tx
.udp_payload
[5] = 0x00;
174 tx
.udp_payload
[6] = 0x00;
175 tx
.udp_payload
[7] = 0x00;
177 tx
.udp_payload
[8] = ssrc
[0];
178 tx
.udp_payload
[9] = ssrc
[1];
179 tx
.udp_payload
[10] = ssrc
[2];
180 tx
.udp_payload
[11] = ssrc
[3];
183 ptr = (u_int8_t*) &csrc;
184 tx.udp_payload[12] = *(ptr+3);
185 tx.udp_payload[13] = *(ptr+2);
186 tx.udp_payload[14] = *(ptr+1);
187 tx.udp_payload[15] = *ptr;
190 // Add the NEW Mausezahn extension header (see mops_ext_rtp.c)
191 tx
.udp_payload
[12] = 0xca; // identifier
192 tx
.udp_payload
[13] = 0xca;
193 tx
.udp_payload
[14] = 0x00;
194 tx
.udp_payload
[15] = 0x04; // length
195 getcurtime(&ts
); // Now add TX timestamp:
196 mops_hton4 ((u_int32_t
*) &ts
.sec
, &tx
.udp_payload
[16]);
197 mops_hton4 ((u_int32_t
*) &ts
.nsec
, &tx
.udp_payload
[20]);
198 // NOTE: The remaining 8 bytes of this extension header are set to zero
199 // via the following code.
201 memset(&tx
.udp_payload
[24], 0x00, (rtp_payload_size
-12)); // payload (considering our 8 byte timestamp)
202 tx
.udp_payload_s
= 12 + rtp_payload_size
; // the latter ist the payload size
204 // ---------- now hand over to UDP -----------------
209 tx
.udp_len
= 8 + tx
.udp_payload_s
;