flowtop: make function nested
[netsniff-ng.git] / src / rtp.c
blob6ce445896283a54237bc6626f125db9e41c1b710
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008 Herbert Haas
4 *
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.
8 *
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
12 * details.
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
21 #include "mz.h"
22 #include "cli.h"
23 #include "mops.h"
25 #define MZ_RTP_HELP \
26 "| RTP type: Send Real Time Protocol packets.\n" \
27 "|\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" \
32 "|\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" \
37 "|\n" \
38 "| You can specify these additional GENERAL options:\n" \
39 "|\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" \
43 "|\n" \
44 "| You can specify these additional UDP/RTP-specific arguments:\n" \
45 "|\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" \
54 "|\n" \
55 "| Additional help: enter 'mz -T rtp help'\n" \
56 "|\n"
60 int create_rtp_packet()
62 u_int8_t byte1, byte2;
63 u_int16_t seqnr;
64 u_int8_t ssrc[4] = {0,0,0,0} ;
65 int ssrc_s = 0;
66 u_int8_t *ptr;
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) ) {
72 if (mz_port)
74 cli_print(gcli, "%s", MZ_RTP_HELP);
75 return -1;
77 else
80 fprintf(stderr,"\n"
81 MAUSEZAHN_VERSION
82 "\n%s", MZ_RTP_HELP);
83 exit(0);
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) {
93 tx.delay = 20000;
96 if (getarg(tx.arg_string,"ssrc", argval)==1) {
97 ssrc_s = str2hex(argval, ssrc, 4);
98 if (ssrc_s<0) {
99 fprintf(stderr, " mz/rtp: invalid ssrc!\n");
100 return -1;
104 // TODO: Optional arguments for RTP
107 // Create header: //
109 // Byte 1
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
117 byte1 = 0x90;
119 // Byte 2
121 // +--+--+--+--+--+--+--+--+
122 // | M| Payload Type |
123 // +--+--+--+--+--+--+--+--+
125 // Marker=0, Payload Type=0 (or 8 alternatively)
127 byte2 = 0x00;
129 // Bytes 3,4
131 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
132 // | Sequence Number |
133 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
135 seqnr = 0x0000;
137 // Bytes 5,6,7,8
139 // Timestamp /* done below */
143 // Bytes 9,10,11,12
145 // Synchronization Source Identifier
148 if (ssrc_s==0) str2hex("ca:fe:fe:ed", ssrc, 4);
150 // Bytes 13,14,15,16
152 // CSRC - Contributing Source Identifiers (optional, only used by mixers)
154 // csrc = 0x00000000;
156 // Bytes 17,18,19,20
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 -----------------
206 tx.dp = 30000;
207 tx.sp = 30000;
209 tx.udp_len = 8 + tx.udp_payload_s;
211 return 0;