├── README ├── autoload_configs ├── acl.conf.xml ├── cdr_csv.conf.xml ├── conference.conf.xml ├── console.conf.xml ├── db.conf.xml ├── event_socket.conf.xml ├── hash.conf.xml ├── httapi.conf.xml ├── ivr.conf.xml ├── local_stream.conf.xml ├── logfile.conf.xml ├── lua.conf.xml ├── modules.conf.xml ├── post_load_modules.conf.xml ├── sofia.conf.xml ├── spandsp.conf.xml ├── switch.conf.xml └── timezones.conf.xml ├── dialplan ├── public.xml └── public │ ├── 10_gateway_inbound.xml │ └── 50_features.xml ├── directory └── stub.xml ├── freeswitch.xml ├── ivr_menus └── stub.xml ├── lang └── en │ ├── en.xml │ └── ivr │ └── stub.xml ├── scripts ├── probe.pl └── run_test ├── sip_profiles ├── external.xml ├── external │ └── stub.xml ├── internal.xml └── internal │ └── stub.xml └── vars.xml /README: -------------------------------------------------------------------------------- 1 | Voice quality probe for end-to-end measurement of jitter and packet loss 2 | ======================================================================== 3 | 4 | This is a clone of minimal FreeSWITCH configuration 5 | (https://github.com/voxserv/freeswitch_conf_minimal) and a few additional 6 | scripts that I built when we needed to measure end-to-end QoS for voice 7 | communication. The same setup is used on the probe computers on both 8 | sides. The test script starts a 30-second SIP call between ports 5080 on 9 | each side and plays MOH in both directions. Few seconds before the call, 10 | tshark is started on both ends, so that RTP stream quality is analyzed 11 | and printed at the end of the call. The results are then stored in a CSV 12 | file in "/var/local/voip_probe/reports" directory. 13 | 14 | The resulting report contains jitter and packet loss statistics for both 15 | ends of the call (on receiving side). 16 | 17 | WARNING: the test script assumes that there is no NAT between the 18 | probes. In case of NAT, far-end statistics will not be properly 19 | displayed. 20 | 21 | Also a tcpdump process is permanently running on every probe and stores 22 | the SIP and RTP packet content on the disk. 23 | 24 | Anonymous FTP server is enabled on the probe, so that reports and packet 25 | captures can be easily downloaded. 26 | 27 | You can set up as many probes as needed with the same installation 28 | sequence, and set up the calls between them in cron jobs. "simple-cdd" 29 | package allows to automate the installation, so that it's replicated on 30 | multiple computers. 31 | 32 | Old Intel Atom netbooks can be used as probes, or also PC Engines' new 33 | APU platform (https://github.com/ssinyagin/pcengines-apu-debian-cd). 34 | 35 | This installation is tested with Debian Wheezy, and should also work 36 | with Debian Squeeze or Ubuntu. 37 | 38 | You need to make sure that root user on every probe can login as root on 39 | the probe on the other end of a call with SSH public key, and the public 40 | key should have empty passphrase. The test script executes tshark on the 41 | far end via SSH. The easiest way is to distribute the same set of 42 | private and public keys and authorized_keys among all probes in the 43 | test. 44 | 45 | 46 | 47 | Installation procedure (Debian Wheezy) 48 | -------------------------------------- 49 | 50 | # required packages 51 | 52 | apt-get update 53 | apt-get install -y \ 54 | ntp curl git tshark tcpdump vsftpd \ 55 | libnet-address-ip-local-perl libdatetime-perl 56 | 57 | # install FreeSWITCH from packages 58 | 59 | cat >/etc/apt/sources.list.d/freeswitch.list </usr/local/sbin/start_voip_sniffer <<'EOF' 86 | #!/bin/sh 87 | /usr/sbin/tcpdump -i eth0 -p -s0 \ 88 | -G 3600 -w /var/local/voip_probe/pcap/voip-%F--%H-%M-%S.pcap \ 89 | udp port 5080 or udp port 5060 or udp portrange 16384-32767 90 | EOF 91 | 92 | chmod 744 /usr/local/sbin/start_voip_sniffer 93 | 94 | cat >/etc/init.d/voip_sniffer <<'EOF' 95 | #!/bin/sh 96 | # 97 | 98 | ### BEGIN INIT INFO 99 | # Provides: voip_sniffer 100 | # Required-Start: $local_fs $remote_fs $network $syslog 101 | # Required-Stop: $local_fs $remote_fs $network $syslog 102 | # Default-Start: 2 3 4 5 103 | # Default-Stop: 104 | # Short-Description: tcpdump for UDP packets 105 | ### END INIT INFO 106 | 107 | PATH=/sbin:/bin:/usr/sbin:/usr/bin 108 | DAEMON="/usr/local/sbin/start_voip_sniffer" 109 | DESC="tcpdump for UDP packets" 110 | VERBOSE=yes 111 | 112 | # Load the VERBOSE setting and other rcS variables 113 | . /lib/init/vars.sh 114 | 115 | # Define LSB log_* functions. 116 | . /lib/lsb/init-functions 117 | 118 | OPTIONS="" 119 | 120 | do_start() 121 | { 122 | start-stop-daemon --start --background \ 123 | --name voip_sniffer --exec $DAEMON \ 124 | || return 1 125 | } 126 | 127 | case "$1" in 128 | start) 129 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 130 | do_start 131 | case "$?" in 132 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 133 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 134 | esac 135 | ;; 136 | stop) 137 | echo not supported 138 | ;; 139 | esac 140 | 141 | exit 0 142 | EOF 143 | 144 | chmod 744 /etc/init.d/voip_sniffer 145 | insserv voip_sniffer 146 | service voip_sniffer start 147 | 148 | 149 | # install SSH keys for root 150 | 151 | mkdir /root/.ssh/ 152 | chmod 700 /root/.ssh/ 153 | 154 | cat >/root/.ssh/id_rsa </root/.ssh/id_rsa.pub <>/etc/vsftpd.conf </etc/cron.d/voip_probe <<'EOF' 196 | 0 0 * * * root find /var/local/voip_probe/pcap -type f -mtime +14 -exec rm '{}' ';' 197 | 2-52/10 * * * * root /etc/freeswitch/scripts/run_test --dest=192.168.1.133 198 | EOF 199 | 200 | 201 | 202 | 203 | AUTHOR 204 | ------ 205 | 206 | Stanislav Sinyagin 207 | ssinyagin@k-open.com 208 | http://www.voxserv.ch/ 209 | 210 | 211 | -------------------------------------------------------------------------------- /autoload_configs/acl.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /autoload_configs/cdr_csv.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /autoload_configs/conference.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /autoload_configs/console.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 33 | 34 | 35 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /autoload_configs/db.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /autoload_configs/event_socket.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /autoload_configs/hash.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /autoload_configs/httapi.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 38 | 39 | 40 | 41 | 42 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 94 | 95 | 96 | 97 | 98 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 112 | 113 | 114 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /autoload_configs/ivr.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /autoload_configs/local_stream.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 49 | 50 | -------------------------------------------------------------------------------- /autoload_configs/logfile.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /autoload_configs/lua.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /autoload_configs/modules.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /autoload_configs/post_load_modules.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /autoload_configs/sofia.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /autoload_configs/spandsp.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /autoload_configs/switch.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 74 | 75 | 76 | 82 | 83 | 84 | 90 | 91 | 92 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /autoload_configs/timezones.conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | -------------------------------------------------------------------------------- /dialplan/public.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /dialplan/public/10_gateway_inbound.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /dialplan/public/50_features.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /directory/stub.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxserv/voip_qos_probe/f89c868b60c505e10d21c5d3472cc56f71c11ea9/directory/stub.xml -------------------------------------------------------------------------------- /freeswitch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 21 | 22 | 23 |
24 | 25 |
26 | 27 |
28 | 29 |
30 | 31 |
32 | 33 |
34 | 35 |
36 | 37 |
38 | 39 |
40 | -------------------------------------------------------------------------------- /ivr_menus/stub.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxserv/voip_qos_probe/f89c868b60c505e10d21c5d3472cc56f71c11ea9/ivr_menus/stub.xml -------------------------------------------------------------------------------- /lang/en/en.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 22 | -------------------------------------------------------------------------------- /lang/en/ivr/stub.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxserv/voip_qos_probe/f89c868b60c505e10d21c5d3472cc56f71c11ea9/lang/en/ivr/stub.xml -------------------------------------------------------------------------------- /scripts/probe.pl: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | 4 | my $dest = $ARGV[0]; 5 | die("Usage: $0 SIPURL\n") unless defined($dest); 6 | 7 | my $s = new freeswitch::Session 8 | ('{origination_caller_id_number=probe}' . 9 | 'sofia/external/' . $dest); 10 | 11 | die("Could not create session") unless defined($s); 12 | 13 | my $started = time(); 14 | while( not $s->answered() ) 15 | { 16 | if( time() > $started + 10 ) 17 | { 18 | die("Timed out waiting for answer"); 19 | } 20 | freeswitch::msleep(500); 21 | } 22 | 23 | my $api = new freeswitch::API; 24 | my $uuid = $s->get_uuid(); 25 | $api->executeString('sched_api +30 none uuid_kill ' . $uuid); 26 | 27 | $s->execute('playback', 'local_stream://moh'); 28 | 29 | 30 | 31 | 32 | 33 | 1; 34 | -------------------------------------------------------------------------------- /scripts/run_test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Getopt::Long; 7 | use Net::Address::IP::Local; 8 | use File::Temp qw(tmpnam); 9 | use IO::File; 10 | use DateTime; 11 | use Data::Dumper; 12 | 13 | my $destip; 14 | my $localip = Net::Address::IP::Local->public_ipv4(); 15 | 16 | 17 | my $ok = GetOptions( 18 | 'dest=s' => \$destip, 19 | 'local=s' => \$localip, 20 | ); 21 | 22 | 23 | if( not $ok or not $destip or scalar(@ARGV) > 0 or $destip !~ /^[0-9.]+$/ ) 24 | { 25 | print STDERR "Usage: $0 --dest=IPADDR\n", 26 | "Options:\n", 27 | " --dest=IPADDR other end probe address\n", 28 | " --local=IPADDR [" . $localip . 29 | "] local IP addr as seen from remote server\n"; 30 | exit(1); 31 | } 32 | 33 | 34 | my $remote_file = tmpnam(); 35 | 36 | my $remotepid = fork(); 37 | if( $remotepid == 0 ) 38 | { 39 | my $sshcmd = 40 | 'ssh' . 41 | ' -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' . 42 | ' root@' . $destip . ' '; 43 | 44 | my $dumpfile = '/tmp/' . $localip . '_' . time(); 45 | 46 | system($sshcmd . 47 | 'timeout 40 /usr/sbin/tcpdump -p -q -w ' . $dumpfile . 48 | ' ip host ' . $localip . ' 2>/dev/null'); 49 | 50 | system($sshcmd . 51 | 'nice tshark -r ' . $dumpfile . ' -z rtp,streams -q >' . 52 | $remote_file . ' 2>/dev/null'); 53 | 54 | system($sshcmd . 55 | 'rm -f ' . $dumpfile . ' 2>/dev/null'); 56 | 57 | exit(0); 58 | } 59 | 60 | my $local_file = tmpnam(); 61 | 62 | my $localpid = fork(); 63 | if( $localpid == 0 ) 64 | { 65 | my $dumpfile = '/tmp/' . $destip . '_' . time(); 66 | 67 | system('timeout 40 /usr/sbin/tcpdump -p -q -w ' . $dumpfile . 68 | ' ip host ' . $destip . ' 2>/dev/null'); 69 | 70 | system('nice tshark -r ' . $dumpfile . ' -z rtp,streams -q >' . 71 | $local_file . ' 2>/dev/null'); 72 | 73 | unlink $dumpfile; 74 | 75 | exit(0); 76 | } 77 | 78 | sleep(3); 79 | 80 | my $now = DateTime->now( time_zone => 'local' ); 81 | 82 | system('fs_cli -x \'perlrun /etc/freeswitch/scripts/probe.pl moh@' . 83 | $destip . ':5080\' >/dev/null'); 84 | 85 | waitpid($remotepid, 0); 86 | waitpid($localpid, 0); 87 | 88 | my %results = 89 | ( 90 | 'date' => $now->ymd, 91 | 'time' => $now->hms, 92 | ); 93 | 94 | 95 | my $fh = IO::File->new($remote_file) or 96 | die("Failed opening $remote_file : $!"); 97 | 98 | while(my $line = $fh->getline()) 99 | { 100 | $line =~ s/^\s+//; 101 | my @parts = split(/\s+/, $line); 102 | 103 | if( $parts[0] eq $localip ) 104 | { 105 | $results{'remote_packets'} = $parts[8]; 106 | $results{'remote_lost'} = $parts[9]; 107 | $results{'remote_max_jitter'} = $parts[12]; 108 | $results{'remote_avg_jitter'} = $parts[13]; 109 | 110 | last; 111 | } 112 | } 113 | 114 | $fh->close; 115 | 116 | $fh = IO::File->new($local_file) or 117 | die("Failed opening $local_file : $!"); 118 | 119 | while(my $line = $fh->getline()) 120 | { 121 | $line =~ s/^\s+//; 122 | my @parts = split(/\s+/, $line); 123 | 124 | if( $parts[0] eq $destip ) 125 | { 126 | $results{'local_packets'} = $parts[8]; 127 | $results{'local_lost'} = $parts[9]; 128 | $results{'local_max_jitter'} = $parts[12]; 129 | $results{'local_avg_jitter'} = $parts[13]; 130 | 131 | last; 132 | } 133 | } 134 | 135 | $fh->close; 136 | 137 | unlink $remote_file; 138 | unlink $local_file; 139 | 140 | #print "Wrote $remote_file $local_file\n"; 141 | #print Dumper(\%results); 142 | 143 | my @columns = 144 | ( 145 | 'date', 146 | 'time', 147 | 'remote_packets', 148 | 'remote_lost', 149 | 'remote_max_jitter', 150 | 'remote_avg_jitter', 151 | 'local_packets', 152 | 'local_lost', 153 | 'local_max_jitter', 154 | 'local_avg_jitter', 155 | ); 156 | 157 | 158 | my $statfile = 159 | '/var/local/voip_probe/reports/' . $localip . '_' . $destip . 160 | '_' . $now->strftime('%Y%m%d'); 161 | 162 | my $printhead = (-f $statfile) ? 0:1; 163 | 164 | $fh = IO::File->new($statfile, 'a') or 165 | die("Failed to open $statfile for writing: $!"); 166 | 167 | if( $printhead ) 168 | { 169 | $fh->print(join(',', @columns) . "\n"); 170 | } 171 | 172 | my @res; 173 | foreach my $col (@columns) 174 | { 175 | my $val = $results{$col}; 176 | $val = '' unless defined($val); 177 | push(@res, $val); 178 | } 179 | 180 | $fh->print(join(',', @res) . "\n"); 181 | 182 | $fh->close; 183 | 184 | #print(join(',', @res) . "\n"); 185 | 186 | 1; 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /sip_profiles/external.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /sip_profiles/external/stub.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxserv/voip_qos_probe/f89c868b60c505e10d21c5d3472cc56f71c11ea9/sip_profiles/external/stub.xml -------------------------------------------------------------------------------- /sip_profiles/internal.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 39 | 40 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 123 | 124 | 125 | 126 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 321 | 322 | 323 | 324 | 325 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 367 | 368 | 371 | 372 | 373 | 377 | 378 | 379 | 380 | 385 | 386 | 387 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 402 | 403 | 404 | 405 | 406 | -------------------------------------------------------------------------------- /sip_profiles/internal/stub.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxserv/voip_qos_probe/f89c868b60c505e10d21c5d3472cc56f71c11ea9/sip_profiles/internal/stub.xml -------------------------------------------------------------------------------- /vars.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 25 | 26 | 27 | 38 | 39 | 40 | 41 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | --------------------------------------------------------------------------------