1 /* 2 * Copyright (c) 2002 - 2003 3 * NetGroup, Politecnico di Torino (Italy) 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the Politecnico di Torino nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifdef HAVE_CONFIG_H 33 #include <config.h> 34 #endif 35 36 #include "ftmacros.h" 37 #include "varattrs.h" 38 39 #include <errno.h> // for the errno variable 40 #include <stdlib.h> // for malloc(), free(), ... 41 #include <string.h> // for strlen(), ... 42 43 #ifdef _WIN32 44 #include <process.h> // for threads 45 #else 46 #include <unistd.h> 47 #include <pthread.h> 48 #include <signal.h> 49 #include <sys/time.h> 50 #include <sys/types.h> // for select() and such 51 #include <pwd.h> // for password management 52 #endif 53 54 #ifdef HAVE_GETSPNAM 55 #include <shadow.h> // for password management 56 #endif 57 58 #include <pcap.h> // for libpcap/WinPcap calls 59 60 #include "fmtutils.h" 61 #include "sockutils.h" // for socket calls 62 #include "portability.h" 63 #include "rpcap-protocol.h" 64 #include "daemon.h" 65 #include "log.h" 66 67 // 68 // Timeout, in seconds, when we're waiting for a client to send us an 69 // authentication request; if they don't send us a request within that 70 // interval, we drop the connection, so we don't stay stuck forever. 71 // 72 #define RPCAP_TIMEOUT_INIT 90 73 74 // 75 // Timeout, in seconds, when we're waiting for an authenticated client 76 // to send us a request, if a capture isn't in progress; if they don't 77 // send us a request within that interval, we drop the connection, so 78 // we don't stay stuck forever. 79 // 80 #define RPCAP_TIMEOUT_RUNTIME 180 81 82 // 83 // Time, in seconds, that we wait after a failed authentication attempt 84 // before processing the next request; this prevents a client from 85 // rapidly trying different accounts or passwords. 86 // 87 #define RPCAP_SUSPEND_WRONGAUTH 1 88 89 // Parameters for the service loop. 90 struct daemon_slpars 91 { 92 SOCKET sockctrl; //!< SOCKET ID of the control connection 93 int isactive; //!< Not null if the daemon has to run in active mode 94 int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise 95 }; 96 97 // 98 // Data for a session managed by a thread. 99 // It includes both a Boolean indicating whether we *have* a thread, 100 // and a platform-dependent (UN*X vs. Windows) identifier for the 101 // thread; on Windows, we could use an invalid handle to indicate 102 // that we don't have a thread, but there *is* no portable "no thread" 103 // value for a pthread_t on UN*X. 104 // 105 struct session { 106 SOCKET sockctrl; 107 SOCKET sockdata; 108 uint8 protocol_version; 109 pcap_t *fp; 110 unsigned int TotCapt; 111 int have_thread; 112 #ifdef _WIN32 113 HANDLE thread; 114 #else 115 pthread_t thread; 116 #endif 117 }; 118 119 // Locally defined functions 120 static int daemon_msg_err(SOCKET sockctrl, uint32 plen); 121 static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen); 122 static int daemon_AuthUserPwd(char *username, char *password, char *errbuf); 123 124 static int daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, 125 uint32 plen); 126 127 static int daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, 128 uint32 plen, char *source, size_t sourcelen); 129 static int daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, 130 uint32 plen, char *source, struct session **sessionp, 131 struct rpcap_sampling *samp_param); 132 static int daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars, 133 struct session *session); 134 135 static int daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars, 136 struct session *session, uint32 plen); 137 static int daemon_unpackapplyfilter(SOCKET sockctrl, struct session *session, uint32 *plenp, char *errbuf); 138 139 static int daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, 140 struct session *session, uint32 plen, struct pcap_stat *stats, 141 unsigned int svrcapt); 142 143 static int daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, 144 uint32 plen, struct rpcap_sampling *samp_param); 145 146 static void daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout); 147 #ifdef _WIN32 148 static unsigned __stdcall daemon_thrdatamain(void *ptr); 149 #else 150 static void *daemon_thrdatamain(void *ptr); 151 static void noop_handler(int sign); 152 #endif 153 154 static int rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp); 155 static int rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf); 156 static int rpcapd_discard(SOCKET sock, uint32 len); 157 static void session_close(struct session *); 158 159 static int is_url(const char *source); 160 161 int 162 daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, 163 int nullAuthAllowed) 164 { 165 struct daemon_slpars pars; // service loop parameters 166 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed 167 char errmsgbuf[PCAP_ERRBUF_SIZE + 1]; // buffer for errors to send to the client 168 int host_port_check_status; 169 int nrecv; 170 struct rpcap_header header; // RPCAP message general header 171 uint32 plen; // payload length from header 172 int authenticated = 0; // 1 if the client has successfully authenticated 173 char source[PCAP_BUF_SIZE+1]; // keeps the string that contains the interface to open 174 int got_source = 0; // 1 if we've gotten the source from an open request 175 #ifndef _WIN32 176 struct sigaction action; 177 #endif 178 struct session *session = NULL; // struct session main variable 179 const char *msg_type_string; // string for message type 180 int client_told_us_to_close = 0; // 1 if the client told us to close the capture 181 182 // needed to save the values of the statistics 183 struct pcap_stat stats; 184 unsigned int svrcapt; 185 186 struct rpcap_sampling samp_param; // in case sampling has been requested 187 188 // Structures needed for the select() call 189 fd_set rfds; // set of socket descriptors we have to check 190 struct timeval tv; // maximum time the select() can block waiting for data 191 int retval; // select() return value 192 193 *errbuf = 0; // Initialize errbuf 194 195 // Set parameters structure 196 pars.sockctrl = sockctrl; 197 pars.isactive = isactive; // active mode 198 pars.nullAuthAllowed = nullAuthAllowed; 199 200 // 201 // We have a connection. 202 // 203 // If it's a passive mode connection, check whether the connecting 204 // host is among the ones allowed. 205 // 206 // In either case, we were handed a copy of the host list; free it 207 // as soon as we're done with it. 208 // 209 if (pars.isactive) 210 { 211 // Nothing to do. 212 free(passiveClients); 213 passiveClients = NULL; 214 } 215 else 216 { 217 struct sockaddr_storage from; 218 socklen_t fromlen; 219 220 // 221 // Get the address of the other end of the connection. 222 // 223 fromlen = sizeof(struct sockaddr_storage); 224 if (getpeername(pars.sockctrl, (struct sockaddr *)&from, 225 &fromlen) == -1) 226 { 227 sock_geterror("getpeername()", errmsgbuf, PCAP_ERRBUF_SIZE); 228 if (rpcap_senderror(pars.sockctrl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) 229 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 230 goto end; 231 } 232 233 // 234 // Are they in the list of host/port combinations we allow? 235 // 236 host_port_check_status = sock_check_hostlist(passiveClients, RPCAP_HOSTLIST_SEP, &from, errmsgbuf, PCAP_ERRBUF_SIZE); 237 free(passiveClients); 238 passiveClients = NULL; 239 if (host_port_check_status < 0) 240 { 241 if (host_port_check_status == -2) { 242 // 243 // We got an error; log it. 244 // 245 rpcapd_log(LOGPRIO_ERROR, "%s", errmsgbuf); 246 } 247 248 // 249 // Sorry, we can't let you in. 250 // 251 if (rpcap_senderror(pars.sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errmsgbuf, errbuf) == -1) 252 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 253 goto end; 254 } 255 } 256 257 #ifndef _WIN32 258 // 259 // Catch SIGUSR1, but do nothing. We use it to interrupt the 260 // capture thread to break it out of a loop in which it's 261 // blocked waiting for packets to arrive. 262 // 263 // We don't want interrupted system calls to restart, so that 264 // the read routine for the pcap_t gets EINTR rather than 265 // restarting if it's blocked in a system call. 266 // 267 memset(&action, 0, sizeof (action)); 268 action.sa_handler = noop_handler; 269 action.sa_flags = 0; 270 sigemptyset(&action.sa_mask); 271 sigaction(SIGUSR1, &action, NULL); 272 #endif 273 274 // 275 // The client must first authenticate; loop until they send us a 276 // message with a version we support and credentials we accept, 277 // they send us a close message indicating that they're giving up, 278 // or we get a network error or other fatal error. 279 // 280 while (!authenticated) 281 { 282 // 283 // If we're not in active mode, we use select(), with a 284 // timeout, to wait for an authentication request; if 285 // the timeout expires, we drop the connection, so that 286 // a client can't just connect to us and leave us 287 // waiting forever. 288 // 289 if (!pars.isactive) 290 { 291 FD_ZERO(&rfds); 292 // We do not have to block here 293 tv.tv_sec = RPCAP_TIMEOUT_INIT; 294 tv.tv_usec = 0; 295 296 FD_SET(pars.sockctrl, &rfds); 297 298 retval = select(pars.sockctrl + 1, &rfds, NULL, NULL, &tv); 299 if (retval == -1) 300 { 301 sock_geterror("select() failed", errmsgbuf, PCAP_ERRBUF_SIZE); 302 if (rpcap_senderror(pars.sockctrl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) 303 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 304 goto end; 305 } 306 307 // The timeout has expired 308 // So, this was a fake connection. Drop it down 309 if (retval == 0) 310 { 311 if (rpcap_senderror(pars.sockctrl, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1) 312 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 313 goto end; 314 } 315 } 316 317 // 318 // Read the message header from the client. 319 // 320 nrecv = rpcapd_recv_msg_header(pars.sockctrl, &header); 321 if (nrecv == -1) 322 { 323 // Fatal error. 324 goto end; 325 } 326 if (nrecv == -2) 327 { 328 // Client closed the connection. 329 goto end; 330 } 331 332 plen = header.plen; 333 334 // 335 // While we're in the authentication pharse, all requests 336 // must use version 0. 337 // 338 if (header.ver != 0) 339 { 340 // 341 // Send it back to them with their version. 342 // 343 if (rpcap_senderror(pars.sockctrl, header.ver, 344 PCAP_ERR_WRONGVER, 345 "RPCAP version in requests in the authentication phase must be 0", 346 errbuf) == -1) 347 { 348 // That failed; log a message and give up. 349 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 350 goto end; 351 } 352 353 // Discard the rest of the message and drop the 354 // connection. 355 (void)rpcapd_discard(pars.sockctrl, plen); 356 goto end; 357 } 358 359 switch (header.type) 360 { 361 case RPCAP_MSG_AUTH_REQ: 362 retval = daemon_msg_auth_req(&pars, plen); 363 if (retval == -1) 364 { 365 // Fatal error; a message has 366 // been logged, so just give up. 367 goto end; 368 } 369 if (retval == -2) 370 { 371 // Non-fatal error; we sent back 372 // an error message, so let them 373 // try again. 374 continue; 375 } 376 377 // OK, we're authenticated; we sent back 378 // a reply, so start serving requests. 379 authenticated = 1; 380 break; 381 382 case RPCAP_MSG_CLOSE: 383 // 384 // The client is giving up. 385 // Discard the rest of the message, if 386 // there is anything more. 387 // 388 (void)rpcapd_discard(pars.sockctrl, plen); 389 // We're done with this client. 390 goto end; 391 392 case RPCAP_MSG_ERROR: 393 // Log this and close the connection? 394 // XXX - is this what happens in active 395 // mode, where *we* initiate the 396 // connection, and the client gives us 397 // an error message rather than a "let 398 // me log in" message, indicating that 399 // we're not allowed to connect to them? 400 (void)daemon_msg_err(pars.sockctrl, plen); 401 goto end; 402 403 case RPCAP_MSG_FINDALLIF_REQ: 404 case RPCAP_MSG_OPEN_REQ: 405 case RPCAP_MSG_STARTCAP_REQ: 406 case RPCAP_MSG_UPDATEFILTER_REQ: 407 case RPCAP_MSG_STATS_REQ: 408 case RPCAP_MSG_ENDCAP_REQ: 409 case RPCAP_MSG_SETSAMPLING_REQ: 410 // 411 // These requests can't be sent until 412 // the client is authenticated. 413 // 414 msg_type_string = rpcap_msg_type_string(header.type); 415 if (msg_type_string != NULL) 416 { 417 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s request sent before authentication was completed", msg_type_string); 418 } 419 else 420 { 421 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message of type %u sent before authentication was completed", header.type); 422 } 423 if (rpcap_senderror(pars.sockctrl, header.ver, 424 PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) 425 { 426 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 427 goto end; 428 } 429 // Discard the rest of the message. 430 if (rpcapd_discard(pars.sockctrl, plen) == -1) 431 { 432 // Network error. 433 goto end; 434 } 435 break; 436 437 case RPCAP_MSG_PACKET: 438 case RPCAP_MSG_FINDALLIF_REPLY: 439 case RPCAP_MSG_OPEN_REPLY: 440 case RPCAP_MSG_STARTCAP_REPLY: 441 case RPCAP_MSG_UPDATEFILTER_REPLY: 442 case RPCAP_MSG_AUTH_REPLY: 443 case RPCAP_MSG_STATS_REPLY: 444 case RPCAP_MSG_ENDCAP_REPLY: 445 case RPCAP_MSG_SETSAMPLING_REPLY: 446 // 447 // These are server-to-client messages. 448 // 449 msg_type_string = rpcap_msg_type_string(header.type); 450 if (msg_type_string != NULL) 451 { 452 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message %s received from client", msg_type_string); 453 } 454 else 455 { 456 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type); 457 } 458 if (rpcap_senderror(pars.sockctrl, header.ver, 459 PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) 460 { 461 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 462 goto end; 463 } 464 // Discard the rest of the message. 465 if (rpcapd_discard(pars.sockctrl, plen) == -1) 466 { 467 // Fatal error. 468 goto end; 469 } 470 break; 471 472 default: 473 // 474 // Unknown message type. 475 // 476 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type); 477 if (rpcap_senderror(pars.sockctrl, header.ver, 478 PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) 479 { 480 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 481 goto end; 482 } 483 // Discard the rest of the message. 484 if (rpcapd_discard(pars.sockctrl, plen) == -1) 485 { 486 // Fatal error. 487 goto end; 488 } 489 break; 490 } 491 } 492 493 // 494 // OK, the client has authenticated itself, and we can start 495 // processing regular requests from it. 496 // 497 498 // 499 // We don't have any statistics yet. 500 // 501 stats.ps_ifdrop = 0; 502 stats.ps_recv = 0; 503 stats.ps_drop = 0; 504 svrcapt = 0; 505 506 // 507 // Service requests. 508 // 509 for (;;) 510 { 511 errbuf[0] = 0; // clear errbuf 512 513 // Avoid zombies connections; check if the connection is opens but no commands are performed 514 // from more than RPCAP_TIMEOUT_RUNTIME 515 // Conditions: 516 // - I have to be in normal mode (no active mode) 517 // - if the device is open, I don't have to be in the middle of a capture (session->sockdata) 518 // - if the device is closed, I have always to check if a new command arrives 519 // 520 // Be carefully: the capture can have been started, but an error occurred (so session != NULL, but 521 // sockdata is 0 522 if ((!pars.isactive) && ((session == NULL) || ((session != NULL) && (session->sockdata == 0)))) 523 { 524 // Check for the initial timeout 525 FD_ZERO(&rfds); 526 // We do not have to block here 527 tv.tv_sec = RPCAP_TIMEOUT_RUNTIME; 528 tv.tv_usec = 0; 529 530 FD_SET(pars.sockctrl, &rfds); 531 532 retval = select(pars.sockctrl + 1, &rfds, NULL, NULL, &tv); 533 if (retval == -1) 534 { 535 sock_geterror("select() failed", errmsgbuf, PCAP_ERRBUF_SIZE); 536 if (rpcap_senderror(pars.sockctrl, 0, 537 PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) 538 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 539 goto end; 540 } 541 542 // The timeout has expired 543 // So, this was a fake connection. Drop it down 544 if (retval == 0) 545 { 546 if (rpcap_senderror(pars.sockctrl, 0, 547 PCAP_ERR_INITTIMEOUT, 548 "The RPCAP initial timeout has expired", 549 errbuf) == -1) 550 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 551 goto end; 552 } 553 } 554 555 // 556 // Read the message header from the client. 557 // 558 nrecv = rpcapd_recv_msg_header(pars.sockctrl, &header); 559 if (nrecv == -1) 560 { 561 // Fatal error. 562 goto end; 563 } 564 if (nrecv == -2) 565 { 566 // Client closed the connection. 567 goto end; 568 } 569 570 plen = header.plen; 571 572 // 573 // Did the client specify a protocol version that we 574 // support? 575 // 576 if (!RPCAP_VERSION_IS_SUPPORTED(header.ver)) 577 { 578 // 579 // Tell them it's not a supported version. 580 // Send the error message with their version, 581 // so they don't reject it as having the wrong 582 // version. 583 // 584 if (rpcap_senderror(pars.sockctrl, 585 header.ver, PCAP_ERR_WRONGVER, 586 "RPCAP version in message isn't supported by the server", 587 errbuf) == -1) 588 { 589 // That failed; log a message and give up. 590 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 591 goto end; 592 } 593 594 // Discard the rest of the message. 595 (void)rpcapd_discard(pars.sockctrl, plen); 596 // Give up on them. 597 goto end; 598 } 599 600 switch (header.type) 601 { 602 case RPCAP_MSG_ERROR: // The other endpoint reported an error 603 { 604 (void)daemon_msg_err(pars.sockctrl, plen); 605 // Do nothing; just exit; the error code is already into the errbuf 606 // XXX - actually exit.... 607 break; 608 } 609 610 case RPCAP_MSG_FINDALLIF_REQ: 611 { 612 if (daemon_msg_findallif_req(header.ver, &pars, plen) == -1) 613 { 614 // Fatal error; a message has 615 // been logged, so just give up. 616 goto end; 617 } 618 break; 619 } 620 621 case RPCAP_MSG_OPEN_REQ: 622 { 623 // 624 // Process the open request, and keep 625 // the source from it, for use later 626 // when the capture is started. 627 // 628 // XXX - we don't care if the client sends 629 // us multiple open requests, the last 630 // one wins. 631 // 632 retval = daemon_msg_open_req(header.ver, &pars, 633 plen, source, sizeof(source)); 634 if (retval == -1) 635 { 636 // Fatal error; a message has 637 // been logged, so just give up. 638 goto end; 639 } 640 got_source = 1; 641 break; 642 } 643 644 case RPCAP_MSG_STARTCAP_REQ: 645 { 646 if (!got_source) 647 { 648 // They never told us what device 649 // to capture on! 650 if (rpcap_senderror(pars.sockctrl, 651 header.ver, 652 PCAP_ERR_STARTCAPTURE, 653 "No capture device was specified", 654 errbuf) == -1) 655 { 656 // Fatal error; log an 657 // error and give up. 658 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 659 goto end; 660 } 661 if (rpcapd_discard(pars.sockctrl, plen) == -1) 662 { 663 goto end; 664 } 665 break; 666 } 667 668 if (daemon_msg_startcap_req(header.ver, &pars, 669 plen, source, &session, &samp_param) == -1) 670 { 671 // Fatal error; a message has 672 // been logged, so just give up. 673 goto end; 674 } 675 break; 676 } 677 678 case RPCAP_MSG_UPDATEFILTER_REQ: 679 { 680 if (session) 681 { 682 if (daemon_msg_updatefilter_req(header.ver, 683 &pars, session, plen) == -1) 684 { 685 // Fatal error; a message has 686 // been logged, so just give up. 687 goto end; 688 } 689 } 690 else 691 { 692 if (rpcap_senderror(pars.sockctrl, 693 header.ver, PCAP_ERR_UPDATEFILTER, 694 "Device not opened. Cannot update filter", 695 errbuf) == -1) 696 { 697 // That failed; log a message and give up. 698 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 699 goto end; 700 } 701 } 702 break; 703 } 704 705 case RPCAP_MSG_CLOSE: // The other endpoint close the pcap session 706 { 707 // 708 // Indicate to our caller that the client 709 // closed the control connection. 710 // This is used only in case of active mode. 711 // 712 client_told_us_to_close = 1; 713 rpcapd_log(LOGPRIO_DEBUG, "The other end system asked to close the connection."); 714 goto end; 715 } 716 717 case RPCAP_MSG_STATS_REQ: 718 { 719 if (daemon_msg_stats_req(header.ver, &pars, 720 session, plen, &stats, svrcapt) == -1) 721 { 722 // Fatal error; a message has 723 // been logged, so just give up. 724 goto end; 725 } 726 break; 727 } 728 729 case RPCAP_MSG_ENDCAP_REQ: // The other endpoint close the current capture session 730 { 731 if (session) 732 { 733 // Save statistics (we can need them in the future) 734 if (pcap_stats(session->fp, &stats)) 735 { 736 svrcapt = session->TotCapt; 737 } 738 else 739 { 740 stats.ps_ifdrop = 0; 741 stats.ps_recv = 0; 742 stats.ps_drop = 0; 743 svrcapt = 0; 744 } 745 746 if (daemon_msg_endcap_req(header.ver, 747 &pars, session) == -1) 748 { 749 free(session); 750 session = NULL; 751 // Fatal error; a message has 752 // been logged, so just give up. 753 goto end; 754 } 755 free(session); 756 session = NULL; 757 } 758 else 759 { 760 rpcap_senderror(pars.sockctrl, 761 header.ver, PCAP_ERR_ENDCAPTURE, 762 "Device not opened. Cannot close the capture", 763 errbuf); 764 } 765 break; 766 } 767 768 case RPCAP_MSG_SETSAMPLING_REQ: 769 { 770 if (daemon_msg_setsampling_req(header.ver, 771 &pars, plen, &samp_param) == -1) 772 { 773 // Fatal error; a message has 774 // been logged, so just give up. 775 goto end; 776 } 777 break; 778 } 779 780 case RPCAP_MSG_AUTH_REQ: 781 { 782 // 783 // We're already authenticated; you don't 784 // get to reauthenticate. 785 // 786 rpcapd_log(LOGPRIO_INFO, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed"); 787 if (rpcap_senderror(pars.sockctrl, header.ver, 788 PCAP_ERR_WRONGMSG, 789 "RPCAP_MSG_AUTH_REQ request sent after authentication was completed", 790 errbuf) == -1) 791 { 792 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 793 goto end; 794 } 795 // Discard the rest of the message. 796 if (rpcapd_discard(pars.sockctrl, plen) == -1) 797 { 798 // Fatal error. 799 goto end; 800 } 801 goto end; 802 803 case RPCAP_MSG_PACKET: 804 case RPCAP_MSG_FINDALLIF_REPLY: 805 case RPCAP_MSG_OPEN_REPLY: 806 case RPCAP_MSG_STARTCAP_REPLY: 807 case RPCAP_MSG_UPDATEFILTER_REPLY: 808 case RPCAP_MSG_AUTH_REPLY: 809 case RPCAP_MSG_STATS_REPLY: 810 case RPCAP_MSG_ENDCAP_REPLY: 811 case RPCAP_MSG_SETSAMPLING_REPLY: 812 // 813 // These are server-to-client messages. 814 // 815 msg_type_string = rpcap_msg_type_string(header.type); 816 if (msg_type_string != NULL) 817 { 818 rpcapd_log(LOGPRIO_INFO, "The client sent a %s server-to-client message", msg_type_string); 819 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message %s received from client", msg_type_string); 820 } 821 else 822 { 823 rpcapd_log(LOGPRIO_INFO, "The client sent a server-to-client message of type %u", header.type); 824 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type); 825 } 826 if (rpcap_senderror(pars.sockctrl, header.ver, 827 PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) 828 { 829 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 830 goto end; 831 } 832 // Discard the rest of the message. 833 if (rpcapd_discard(pars.sockctrl, plen) == -1) 834 { 835 // Fatal error. 836 goto end; 837 } 838 goto end; 839 840 default: 841 // 842 // Unknown message type. 843 // 844 rpcapd_log(LOGPRIO_INFO, "The client sent a message of type %u", header.type); 845 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type); 846 if (rpcap_senderror(pars.sockctrl, header.ver, 847 PCAP_ERR_WRONGMSG, errbuf, errmsgbuf) == -1) 848 { 849 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 850 goto end; 851 } 852 // Discard the rest of the message. 853 if (rpcapd_discard(pars.sockctrl, plen) == -1) 854 { 855 // Fatal error. 856 goto end; 857 } 858 goto end; 859 } 860 } 861 } 862 863 end: 864 // The service loop is finishing up. 865 // If we have a capture session running, close it. 866 if (session) 867 { 868 session_close(session); 869 free(session); 870 session = NULL; 871 } 872 873 sock_close(sockctrl, NULL, 0); 874 875 // Print message and return 876 rpcapd_log(LOGPRIO_DEBUG, "I'm exiting from the child loop"); 877 878 return client_told_us_to_close; 879 } 880 881 /* 882 * This handles the RPCAP_MSG_ERR message. 883 */ 884 static int 885 daemon_msg_err(SOCKET sockctrl, uint32 plen) 886 { 887 char errbuf[PCAP_ERRBUF_SIZE]; 888 char remote_errbuf[PCAP_ERRBUF_SIZE]; 889 890 if (plen >= PCAP_ERRBUF_SIZE) 891 { 892 /* 893 * Message is too long; just read as much of it as we 894 * can into the buffer provided, and discard the rest. 895 */ 896 if (sock_recv(sockctrl, remote_errbuf, PCAP_ERRBUF_SIZE - 1, 897 SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, 898 PCAP_ERRBUF_SIZE) == -1) 899 { 900 // Network error. 901 rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); 902 return -1; 903 } 904 if (rpcapd_discard(sockctrl, plen - (PCAP_ERRBUF_SIZE - 1)) == -1) 905 { 906 // Network error. 907 return -1; 908 } 909 910 /* 911 * Null-terminate it. 912 */ 913 remote_errbuf[PCAP_ERRBUF_SIZE - 1] = '\0'; 914 } 915 else if (plen == 0) 916 { 917 /* Empty error string. */ 918 remote_errbuf[0] = '\0'; 919 } 920 else 921 { 922 if (sock_recv(sockctrl, remote_errbuf, plen, 923 SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, 924 PCAP_ERRBUF_SIZE) == -1) 925 { 926 // Network error. 927 rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); 928 return -1; 929 } 930 931 /* 932 * Null-terminate it. 933 */ 934 remote_errbuf[plen] = '\0'; 935 } 936 // Log the message 937 rpcapd_log(LOGPRIO_ERROR, "Error from client: %s", remote_errbuf); 938 return 0; 939 } 940 941 /* 942 * This handles the RPCAP_MSG_AUTH_REQ message. 943 * It checks if the authentication credentials supplied by the user are valid. 944 * 945 * This function is called if the daemon receives a RPCAP_MSG_AUTH_REQ 946 * message in its authentication loop. It reads the body of the 947 * authentication message from the network and checks whether the 948 * credentials are valid. 949 * 950 * \param sockctrl: the socket for the control connection. 951 * 952 * \param nullAuthAllowed: '1' if the NULL authentication is allowed. 953 * 954 * \param errbuf: a user-allocated buffer in which the error message 955 * (if one) has to be written. It must be at least PCAP_ERRBUF_SIZE 956 * bytes long. 957 * 958 * \return '0' if everything is fine, '-1' if an unrecoverable error occurred, 959 * or '-2' if the authentication failed. For errors, an error message is 960 * returned in the 'errbuf' variable; this gives a message for the 961 * unrecoverable error or for the authentication failure. 962 */ 963 static int 964 daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) 965 { 966 char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors 967 char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client 968 int status; 969 struct rpcap_auth auth; // RPCAP authentication header 970 char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered 971 int sendbufidx = 0; // index which keeps the number of bytes currently buffered 972 struct rpcap_authreply *authreply; // authentication reply message 973 974 status = rpcapd_recv(pars->sockctrl, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf); 975 if (status == -1) 976 { 977 return -1; 978 } 979 if (status == -2) 980 { 981 goto error; 982 } 983 984 switch (ntohs(auth.type)) 985 { 986 case RPCAP_RMTAUTH_NULL: 987 { 988 if (!pars->nullAuthAllowed) 989 { 990 // Send the client an error reply. 991 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, 992 "Authentication failed; NULL authentication not permitted."); 993 if (rpcap_senderror(pars->sockctrl, 0, 994 PCAP_ERR_AUTH_FAILED, errmsgbuf, errbuf) == -1) 995 { 996 // That failed; log a message and give up. 997 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 998 return -1; 999 } 1000 goto error_noreply; 1001 } 1002 break; 1003 } 1004 1005 case RPCAP_RMTAUTH_PWD: 1006 { 1007 char *username, *passwd; 1008 uint32 usernamelen, passwdlen; 1009 1010 usernamelen = ntohs(auth.slen1); 1011 username = (char *) malloc (usernamelen + 1); 1012 if (username == NULL) 1013 { 1014 pcap_fmt_errmsg_for_errno(errmsgbuf, 1015 PCAP_ERRBUF_SIZE, errno, "malloc() failed"); 1016 goto error; 1017 } 1018 status = rpcapd_recv(pars->sockctrl, username, usernamelen, &plen, errmsgbuf); 1019 if (status == -1) 1020 { 1021 free(username); 1022 return -1; 1023 } 1024 if (status == -2) 1025 { 1026 free(username); 1027 goto error; 1028 } 1029 username[usernamelen] = '\0'; 1030 1031 passwdlen = ntohs(auth.slen2); 1032 passwd = (char *) malloc (passwdlen + 1); 1033 if (passwd == NULL) 1034 { 1035 pcap_fmt_errmsg_for_errno(errmsgbuf, 1036 PCAP_ERRBUF_SIZE, errno, "malloc() failed"); 1037 free(username); 1038 goto error; 1039 } 1040 status = rpcapd_recv(pars->sockctrl, passwd, passwdlen, &plen, errmsgbuf); 1041 if (status == -1) 1042 { 1043 free(username); 1044 free(passwd); 1045 return -1; 1046 } 1047 if (status == -2) 1048 { 1049 free(username); 1050 free(passwd); 1051 goto error; 1052 } 1053 passwd[passwdlen] = '\0'; 1054 1055 if (daemon_AuthUserPwd(username, passwd, errmsgbuf)) 1056 { 1057 // 1058 // Authentication failed. Let the client 1059 // know. 1060 // 1061 free(username); 1062 free(passwd); 1063 if (rpcap_senderror(pars->sockctrl, 0, 1064 PCAP_ERR_AUTH_FAILED, errmsgbuf, errbuf) == -1) 1065 { 1066 // That failed; log a message and give up. 1067 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1068 return -1; 1069 } 1070 1071 // 1072 // Suspend for 1 second, so that they can't 1073 // hammer us with repeated tries with an 1074 // attack such as a dictionary attack. 1075 // 1076 // WARNING: this delay is inserted only 1077 // at this point; if the client closes the 1078 // connection and reconnects, the suspension 1079 // time does not have any effect. 1080 // 1081 sleep_secs(RPCAP_SUSPEND_WRONGAUTH); 1082 goto error_noreply; 1083 } 1084 1085 free(username); 1086 free(passwd); 1087 break; 1088 } 1089 1090 default: 1091 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, 1092 "Authentication type not recognized."); 1093 if (rpcap_senderror(pars->sockctrl, 0, 1094 PCAP_ERR_AUTH_TYPE_NOTSUP, errmsgbuf, errbuf) == -1) 1095 { 1096 // That failed; log a message and give up. 1097 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1098 return -1; 1099 } 1100 goto error_noreply; 1101 } 1102 1103 // The authentication succeeded; let the client know. 1104 if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx, 1105 RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1106 goto error; 1107 1108 rpcap_createhdr((struct rpcap_header *) sendbuf, 0, 1109 RPCAP_MSG_AUTH_REPLY, 0, sizeof(struct rpcap_authreply)); 1110 1111 authreply = (struct rpcap_authreply *) &sendbuf[sendbufidx]; 1112 1113 if (sock_bufferize(NULL, sizeof(struct rpcap_authreply), NULL, &sendbufidx, 1114 RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1115 goto error; 1116 1117 // 1118 // Indicate to our peer what versions we support. 1119 // 1120 memset(authreply, 0, sizeof(struct rpcap_authreply)); 1121 authreply->minvers = RPCAP_MIN_VERSION; 1122 authreply->maxvers = RPCAP_MAX_VERSION; 1123 1124 // Send the reply. 1125 if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) 1126 { 1127 // That failed; log a messsage and give up. 1128 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1129 return -1; 1130 } 1131 1132 // Check if all the data has been read; if not, discard the data in excess 1133 if (rpcapd_discard(pars->sockctrl, plen) == -1) 1134 { 1135 return -1; 1136 } 1137 1138 return 0; 1139 1140 error: 1141 if (rpcap_senderror(pars->sockctrl, 0, PCAP_ERR_AUTH, errmsgbuf, 1142 errbuf) == -1) 1143 { 1144 // That failed; log a message and give up. 1145 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1146 return -1; 1147 } 1148 1149 error_noreply: 1150 // Check if all the data has been read; if not, discard the data in excess 1151 if (rpcapd_discard(pars->sockctrl, plen) == -1) 1152 { 1153 return -1; 1154 } 1155 1156 return -2; 1157 } 1158 1159 static int 1160 daemon_AuthUserPwd(char *username, char *password, char *errbuf) 1161 { 1162 #ifdef _WIN32 1163 /* 1164 * Warning: the user which launches the process must have the 1165 * SE_TCB_NAME right. 1166 * This corresponds to have the "Act as part of the Operating System" 1167 * turned on (administrative tools, local security settings, local 1168 * policies, user right assignment) 1169 * However, it seems to me that if you run it as a service, this 1170 * right should be provided by default. 1171 * 1172 * XXX - hopefully, this returns errors such as ERROR_LOGON_FAILURE, 1173 * which merely indicates that the user name or password is 1174 * incorrect, not whether it's the user name or the password 1175 * that's incorrect, so a client that's trying to brute-force 1176 * accounts doesn't know whether it's the user name or the 1177 * password that's incorrect, so it doesn't know whether to 1178 * stop trying to log in with a given user name and move on 1179 * to another user name. 1180 */ 1181 DWORD error; 1182 HANDLE Token; 1183 char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to log 1184 1185 if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0) 1186 { 1187 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); 1188 error = GetLastError(); 1189 if (error != ERROR_LOGON_FAILURE) 1190 { 1191 // Some error other than an authentication error; 1192 // log it. 1193 pcap_fmt_errmsg_for_win32_err(errmsgbuf, 1194 PCAP_ERRBUF_SIZE, error, "LogonUser() failed"); 1195 rpcapd_log(LOGPRIO_ERROR, "%s", errmsgbuf); 1196 } 1197 return -1; 1198 } 1199 1200 // This call should change the current thread to the selected user. 1201 // I didn't test it. 1202 if (ImpersonateLoggedOnUser(Token) == 0) 1203 { 1204 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); 1205 pcap_fmt_errmsg_for_win32_err(errmsgbuf, PCAP_ERRBUF_SIZE, 1206 GetLastError(), "ImpersonateLoggedOnUser() failed"); 1207 rpcapd_log(LOGPRIO_ERROR, "%s", errmsgbuf); 1208 CloseHandle(Token); 1209 return -1; 1210 } 1211 1212 CloseHandle(Token); 1213 return 0; 1214 1215 #else 1216 /* 1217 * See 1218 * 1219 * http://www.unixpapa.com/incnote/passwd.html 1220 * 1221 * We use the Solaris/Linux shadow password authentication if 1222 * we have getspnam(), otherwise we just do traditional 1223 * authentication, which, on some platforms, might work, even 1224 * with shadow passwords, if we're running as root. Traditional 1225 * authenticaion won't work if we're not running as root, as 1226 * I think these days all UN*Xes either won't return the password 1227 * at all with getpwnam() or will only do so if you're root. 1228 * 1229 * XXX - perhaps what we *should* be using is PAM, if we have 1230 * it. That might hide all the details of username/password 1231 * authentication, whether it's done with a visible-to-root- 1232 * only password database or some other authentication mechanism, 1233 * behind its API. 1234 */ 1235 int error; 1236 struct passwd *user; 1237 char *user_password; 1238 #ifdef HAVE_GETSPNAM 1239 struct spwd *usersp; 1240 #endif 1241 char *crypt_password; 1242 1243 // This call is needed to get the uid 1244 if ((user = getpwnam(username)) == NULL) 1245 { 1246 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); 1247 return -1; 1248 } 1249 1250 #ifdef HAVE_GETSPNAM 1251 // This call is needed to get the password; otherwise 'x' is returned 1252 if ((usersp = getspnam(username)) == NULL) 1253 { 1254 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); 1255 return -1; 1256 } 1257 user_password = usersp->sp_pwdp; 1258 #else 1259 /* 1260 * XXX - what about other platforms? 1261 * The unixpapa.com page claims this Just Works on *BSD if you're 1262 * running as root - it's from 2000, so it doesn't indicate whether 1263 * macOS (which didn't come out until 2001, under the name Mac OS 1264 * X) behaves like the *BSDs or not, and might also work on AIX. 1265 * HP-UX does something else. 1266 * 1267 * Again, hopefully PAM hides all that. 1268 */ 1269 user_password = user->pw_passwd; 1270 #endif 1271 1272 // 1273 // The Single UNIX Specification says that if crypt() fails it 1274 // sets errno, but some implementatons that haven't been run 1275 // through the SUS test suite might not do so. 1276 // 1277 errno = 0; 1278 crypt_password = crypt(password, user_password); 1279 if (crypt_password == NULL) 1280 { 1281 error = errno; 1282 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); 1283 if (error == 0) 1284 { 1285 // It didn't set errno. 1286 rpcapd_log(LOGPRIO_ERROR, "crypt() failed"); 1287 } 1288 else 1289 { 1290 rpcapd_log(LOGPRIO_ERROR, "crypt() failed: %s", 1291 strerror(error)); 1292 } 1293 return -1; 1294 } 1295 if (strcmp(user_password, crypt_password) != 0) 1296 { 1297 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); 1298 return -1; 1299 } 1300 1301 if (setuid(user->pw_uid)) 1302 { 1303 error = errno; 1304 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1305 error, "setuid"); 1306 rpcapd_log(LOGPRIO_ERROR, "setuid() failed: %s", 1307 strerror(error)); 1308 return -1; 1309 } 1310 1311 /* if (setgid(user->pw_gid)) 1312 { 1313 error = errno; 1314 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1315 errno, "setgid"); 1316 rpcapd_log(LOGPRIO_ERROR, "setgid() failed: %s", 1317 strerror(error)); 1318 return -1; 1319 } 1320 */ 1321 return 0; 1322 1323 #endif 1324 1325 } 1326 1327 static int 1328 daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) 1329 { 1330 char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors 1331 char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client 1332 char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered 1333 int sendbufidx = 0; // index which keeps the number of bytes currently buffered 1334 pcap_if_t *alldevs = NULL; // pointer to the header of the interface chain 1335 pcap_if_t *d; // temp pointer needed to scan the interface chain 1336 struct pcap_addr *address; // pcap structure that keeps a network address of an interface 1337 struct rpcap_findalldevs_if *findalldevs_if;// rpcap structure that packet all the data of an interface together 1338 uint32 replylen; // length of reply payload 1339 uint16 nif = 0; // counts the number of interface listed 1340 1341 // Discard the rest of the message; there shouldn't be any payload. 1342 if (rpcapd_discard(pars->sockctrl, plen) == -1) 1343 { 1344 // Network error. 1345 return -1; 1346 } 1347 1348 // Retrieve the device list 1349 if (pcap_findalldevs(&alldevs, errmsgbuf) == -1) 1350 goto error; 1351 1352 if (alldevs == NULL) 1353 { 1354 if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_NOREMOTEIF, 1355 "No interfaces found! Make sure libpcap/WinPcap is properly installed" 1356 " and you have the right to access to the remote device.", 1357 errbuf) == -1) 1358 { 1359 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1360 return -1; 1361 } 1362 return 0; 1363 } 1364 1365 // This checks the number of interfaces and computes the total 1366 // length of the payload. 1367 replylen = 0; 1368 for (d = alldevs; d != NULL; d = d->next) 1369 { 1370 nif++; 1371 1372 if (d->description) 1373 replylen += strlen(d->description); 1374 if (d->name) 1375 replylen += strlen(d->name); 1376 1377 replylen += sizeof(struct rpcap_findalldevs_if); 1378 1379 for (address = d->addresses; address != NULL; address = address->next) 1380 { 1381 /* 1382 * Send only IPv4 and IPv6 addresses over the wire. 1383 */ 1384 switch (address->addr->sa_family) 1385 { 1386 case AF_INET: 1387 #ifdef AF_INET6 1388 case AF_INET6: 1389 #endif 1390 replylen += (sizeof(struct rpcap_sockaddr) * 4); 1391 break; 1392 1393 default: 1394 break; 1395 } 1396 } 1397 } 1398 1399 // RPCAP findalldevs command 1400 if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, 1401 &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, 1402 PCAP_ERRBUF_SIZE) == -1) 1403 goto error; 1404 1405 rpcap_createhdr((struct rpcap_header *) sendbuf, ver, 1406 RPCAP_MSG_FINDALLIF_REPLY, nif, replylen); 1407 1408 // send the interface list 1409 for (d = alldevs; d != NULL; d = d->next) 1410 { 1411 uint16 lname, ldescr; 1412 1413 findalldevs_if = (struct rpcap_findalldevs_if *) &sendbuf[sendbufidx]; 1414 1415 if (sock_bufferize(NULL, sizeof(struct rpcap_findalldevs_if), NULL, 1416 &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1417 goto error; 1418 1419 memset(findalldevs_if, 0, sizeof(struct rpcap_findalldevs_if)); 1420 1421 if (d->description) ldescr = (short) strlen(d->description); 1422 else ldescr = 0; 1423 if (d->name) lname = (short) strlen(d->name); 1424 else lname = 0; 1425 1426 findalldevs_if->desclen = htons(ldescr); 1427 findalldevs_if->namelen = htons(lname); 1428 findalldevs_if->flags = htonl(d->flags); 1429 1430 for (address = d->addresses; address != NULL; address = address->next) 1431 { 1432 /* 1433 * Send only IPv4 and IPv6 addresses over the wire. 1434 */ 1435 switch (address->addr->sa_family) 1436 { 1437 case AF_INET: 1438 #ifdef AF_INET6 1439 case AF_INET6: 1440 #endif 1441 findalldevs_if->naddr++; 1442 break; 1443 1444 default: 1445 break; 1446 } 1447 } 1448 findalldevs_if->naddr = htons(findalldevs_if->naddr); 1449 1450 if (sock_bufferize(d->name, lname, sendbuf, &sendbufidx, 1451 RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf, 1452 PCAP_ERRBUF_SIZE) == -1) 1453 goto error; 1454 1455 if (sock_bufferize(d->description, ldescr, sendbuf, &sendbufidx, 1456 RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf, 1457 PCAP_ERRBUF_SIZE) == -1) 1458 goto error; 1459 1460 // send all addresses 1461 for (address = d->addresses; address != NULL; address = address->next) 1462 { 1463 struct rpcap_sockaddr *sockaddr; 1464 1465 /* 1466 * Send only IPv4 and IPv6 addresses over the wire. 1467 */ 1468 switch (address->addr->sa_family) 1469 { 1470 case AF_INET: 1471 #ifdef AF_INET6 1472 case AF_INET6: 1473 #endif 1474 sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx]; 1475 if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL, 1476 &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1477 goto error; 1478 daemon_seraddr((struct sockaddr_storage *) address->addr, sockaddr); 1479 1480 sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx]; 1481 if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL, 1482 &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1483 goto error; 1484 daemon_seraddr((struct sockaddr_storage *) address->netmask, sockaddr); 1485 1486 sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx]; 1487 if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL, 1488 &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1489 goto error; 1490 daemon_seraddr((struct sockaddr_storage *) address->broadaddr, sockaddr); 1491 1492 sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx]; 1493 if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL, 1494 &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1495 goto error; 1496 daemon_seraddr((struct sockaddr_storage *) address->dstaddr, sockaddr); 1497 break; 1498 1499 default: 1500 break; 1501 } 1502 } 1503 } 1504 1505 // We no longer need the device list. Free it. 1506 pcap_freealldevs(alldevs); 1507 1508 // Send a final command that says "now send it!" 1509 if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) 1510 { 1511 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1512 return -1; 1513 } 1514 1515 return 0; 1516 1517 error: 1518 if (alldevs) 1519 pcap_freealldevs(alldevs); 1520 1521 if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_FINDALLIF, 1522 errmsgbuf, errbuf) == -1) 1523 { 1524 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1525 return -1; 1526 } 1527 return 0; 1528 } 1529 1530 /* 1531 \param plen: the length of the current message (needed in order to be able 1532 to discard excess data in the message, if present) 1533 */ 1534 static int 1535 daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, 1536 char *source, size_t sourcelen) 1537 { 1538 char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors 1539 char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client 1540 pcap_t *fp; // pcap_t main variable 1541 int nread; 1542 char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered 1543 int sendbufidx = 0; // index which keeps the number of bytes currently buffered 1544 struct rpcap_openreply *openreply; // open reply message 1545 1546 if (plen > sourcelen - 1) 1547 { 1548 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string too long"); 1549 goto error; 1550 } 1551 1552 nread = sock_recv(pars->sockctrl, source, plen, 1553 SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE); 1554 if (nread == -1) 1555 { 1556 rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); 1557 return -1; 1558 } 1559 source[nread] = '\0'; 1560 plen -= nread; 1561 1562 // Is this a URL rather than a device? 1563 // If so, reject it. 1564 if (is_url(source)) 1565 { 1566 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string refers to a remote device"); 1567 goto error; 1568 } 1569 1570 // Open the selected device 1571 // This is a fake open, since we do that only to get the needed parameters, then we close the device again 1572 if ((fp = pcap_open_live(source, 1573 1500 /* fake snaplen */, 1574 0 /* no promis */, 1575 1000 /* fake timeout */, 1576 errmsgbuf)) == NULL) 1577 goto error; 1578 1579 // Now, I can send a RPCAP open reply message 1580 if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx, 1581 RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1582 goto error; 1583 1584 rpcap_createhdr((struct rpcap_header *) sendbuf, ver, 1585 RPCAP_MSG_OPEN_REPLY, 0, sizeof(struct rpcap_openreply)); 1586 1587 openreply = (struct rpcap_openreply *) &sendbuf[sendbufidx]; 1588 1589 if (sock_bufferize(NULL, sizeof(struct rpcap_openreply), NULL, &sendbufidx, 1590 RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1591 goto error; 1592 1593 memset(openreply, 0, sizeof(struct rpcap_openreply)); 1594 openreply->linktype = htonl(pcap_datalink(fp)); 1595 openreply->tzoff = 0; /* This is always 0 for live captures */ 1596 1597 // We're done with the pcap_t. 1598 pcap_close(fp); 1599 1600 // Send the reply. 1601 if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) 1602 { 1603 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1604 return -1; 1605 } 1606 return 0; 1607 1608 error: 1609 if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_OPEN, 1610 errmsgbuf, errbuf) == -1) 1611 { 1612 // That failed; log a message and give up. 1613 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1614 return -1; 1615 } 1616 1617 // Check if all the data has been read; if not, discard the data in excess 1618 if (rpcapd_discard(pars->sockctrl, plen) == -1) 1619 { 1620 return -1; 1621 } 1622 return 0; 1623 } 1624 1625 /* 1626 \param plen: the length of the current message (needed in order to be able 1627 to discard excess data in the message, if present) 1628 */ 1629 static int 1630 daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, 1631 char *source, struct session **sessionp, 1632 struct rpcap_sampling *samp_param _U_) 1633 { 1634 char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors 1635 char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client 1636 char portdata[PCAP_BUF_SIZE]; // temp variable needed to derive the data port 1637 char peerhost[PCAP_BUF_SIZE]; // temp variable needed to derive the host name of our peer 1638 struct session *session = NULL; // saves state of session 1639 int status; 1640 char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered 1641 int sendbufidx = 0; // index which keeps the number of bytes currently buffered 1642 1643 // socket-related variables 1644 struct addrinfo hints; // temp, needed to open a socket connection 1645 struct addrinfo *addrinfo; // temp, needed to open a socket connection 1646 struct sockaddr_storage saddr; // temp, needed to retrieve the network data port chosen on the local machine 1647 socklen_t saddrlen; // temp, needed to retrieve the network data port chosen on the local machine 1648 int ret; // return value from functions 1649 1650 // RPCAP-related variables 1651 struct rpcap_startcapreq startcapreq; // start capture request message 1652 struct rpcap_startcapreply *startcapreply; // start capture reply message 1653 int serveropen_dp; // keeps who is going to open the data connection 1654 1655 addrinfo = NULL; 1656 1657 status = rpcapd_recv(pars->sockctrl, (char *) &startcapreq, 1658 sizeof(struct rpcap_startcapreq), &plen, errmsgbuf); 1659 if (status == -1) 1660 { 1661 goto fatal_error; 1662 } 1663 if (status == -2) 1664 { 1665 goto error; 1666 } 1667 1668 startcapreq.flags = ntohs(startcapreq.flags); 1669 1670 // Create a session structure 1671 session = malloc(sizeof(struct session)); 1672 if (session == NULL) 1673 { 1674 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Can't allocate session structure"); 1675 goto error; 1676 } 1677 1678 session->sockdata = INVALID_SOCKET; 1679 // We don't have a thread yet. 1680 session->have_thread = 0; 1681 // 1682 // We *shouldn't* have to initialize the thread indicator 1683 // itself, because the compiler *should* realize that we 1684 // only use this if have_thread isn't 0, but we *do* have 1685 // to do it, because not all compilers *do* realize that. 1686 // 1687 // There is no "invalid thread handle" value for a UN*X 1688 // pthread_t, so we just zero it out. 1689 // 1690 #ifdef _WIN32 1691 session->thread = INVALID_HANDLE_VALUE; 1692 #else 1693 memset(&session->thread, 0, sizeof(session->thread)); 1694 #endif 1695 1696 // Open the selected device 1697 if ((session->fp = pcap_open_live(source, 1698 ntohl(startcapreq.snaplen), 1699 (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_PROMISC) ? 1 : 0 /* local device, other flags not needed */, 1700 ntohl(startcapreq.read_timeout), 1701 errmsgbuf)) == NULL) 1702 goto error; 1703 1704 #if 0 1705 // Apply sampling parameters 1706 fp->rmt_samp.method = samp_param->method; 1707 fp->rmt_samp.value = samp_param->value; 1708 #endif 1709 1710 /* 1711 We're in active mode if: 1712 - we're using TCP, and the user wants us to be in active mode 1713 - we're using UDP 1714 */ 1715 serveropen_dp = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_SERVEROPEN) || (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) || pars->isactive; 1716 1717 /* 1718 Gets the sockaddr structure referred to the other peer in the ctrl connection 1719 1720 We need that because: 1721 - if we're in passive mode, we need to know the address family we want to use 1722 (the same used for the ctrl socket) 1723 - if we're in active mode, we need to know the network address of the other host 1724 we want to connect to 1725 */ 1726 saddrlen = sizeof(struct sockaddr_storage); 1727 if (getpeername(pars->sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) 1728 { 1729 sock_geterror("getpeername()", errmsgbuf, PCAP_ERRBUF_SIZE); 1730 goto error; 1731 } 1732 1733 memset(&hints, 0, sizeof(struct addrinfo)); 1734 hints.ai_socktype = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) ? SOCK_DGRAM : SOCK_STREAM; 1735 hints.ai_family = saddr.ss_family; 1736 1737 // Now we have to create a new socket to send packets 1738 if (serveropen_dp) // Data connection is opened by the server toward the client 1739 { 1740 pcap_snprintf(portdata, sizeof portdata, "%d", ntohs(startcapreq.portdata)); 1741 1742 // Get the name of the other peer (needed to connect to that specific network address) 1743 if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peerhost, 1744 sizeof(peerhost), NULL, 0, NI_NUMERICHOST)) 1745 { 1746 sock_geterror("getnameinfo()", errmsgbuf, PCAP_ERRBUF_SIZE); 1747 goto error; 1748 } 1749 1750 if (sock_initaddress(peerhost, portdata, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1751 goto error; 1752 1753 if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) 1754 goto error; 1755 } 1756 else // Data connection is opened by the client toward the server 1757 { 1758 hints.ai_flags = AI_PASSIVE; 1759 1760 // Let's the server socket pick up a free network port for us 1761 if (sock_initaddress(NULL, "0", &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1762 goto error; 1763 1764 if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) 1765 goto error; 1766 1767 // get the complete sockaddr structure used in the data connection 1768 saddrlen = sizeof(struct sockaddr_storage); 1769 if (getsockname(session->sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1) 1770 { 1771 sock_geterror("getsockname()", errmsgbuf, PCAP_ERRBUF_SIZE); 1772 goto error; 1773 } 1774 1775 // Get the local port the system picked up 1776 if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL, 1777 0, portdata, sizeof(portdata), NI_NUMERICSERV)) 1778 { 1779 sock_geterror("getnameinfo()", errmsgbuf, PCAP_ERRBUF_SIZE); 1780 goto error; 1781 } 1782 } 1783 1784 // addrinfo is no longer used 1785 freeaddrinfo(addrinfo); 1786 addrinfo = NULL; 1787 1788 // Needed to send an error on the ctrl connection 1789 session->sockctrl = pars->sockctrl; 1790 session->protocol_version = ver; 1791 1792 // Now I can set the filter 1793 ret = daemon_unpackapplyfilter(pars->sockctrl, session, &plen, errmsgbuf); 1794 if (ret == -1) 1795 { 1796 // Fatal error. A message has been logged; just give up. 1797 goto fatal_error; 1798 } 1799 if (ret == -2) 1800 { 1801 // Non-fatal error. Send an error message to the client. 1802 goto error; 1803 } 1804 1805 // Now, I can send a RPCAP start capture reply message 1806 if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx, 1807 RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1808 goto error; 1809 1810 rpcap_createhdr((struct rpcap_header *) sendbuf, ver, 1811 RPCAP_MSG_STARTCAP_REPLY, 0, sizeof(struct rpcap_startcapreply)); 1812 1813 startcapreply = (struct rpcap_startcapreply *) &sendbuf[sendbufidx]; 1814 1815 if (sock_bufferize(NULL, sizeof(struct rpcap_startcapreply), NULL, 1816 &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 1817 goto error; 1818 1819 memset(startcapreply, 0, sizeof(struct rpcap_startcapreply)); 1820 startcapreply->bufsize = htonl(pcap_bufsize(session->fp)); 1821 1822 if (!serveropen_dp) 1823 { 1824 unsigned short port = (unsigned short)strtoul(portdata,NULL,10); 1825 startcapreply->portdata = htons(port); 1826 } 1827 1828 if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) 1829 { 1830 // That failed; log a message and give up. 1831 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1832 goto fatal_error; 1833 } 1834 1835 if (!serveropen_dp) 1836 { 1837 SOCKET socktemp; // We need another socket, since we're going to accept() a connection 1838 1839 // Connection creation 1840 saddrlen = sizeof(struct sockaddr_storage); 1841 1842 socktemp = accept(session->sockdata, (struct sockaddr *) &saddr, &saddrlen); 1843 1844 if (socktemp == INVALID_SOCKET) 1845 { 1846 sock_geterror("accept()", errbuf, PCAP_ERRBUF_SIZE); 1847 rpcapd_log(LOGPRIO_ERROR, "Accept of data connection failed: %s", 1848 errbuf); 1849 goto error; 1850 } 1851 1852 // Now that I accepted the connection, the server socket is no longer needed 1853 sock_close(session->sockdata, NULL, 0); 1854 session->sockdata = socktemp; 1855 } 1856 1857 // Now we have to create a new thread to receive packets 1858 #ifdef _WIN32 1859 session->thread = (HANDLE)_beginthreadex(NULL, 0, daemon_thrdatamain, 1860 (void *) session, 0, NULL); 1861 if (session->thread == 0) 1862 { 1863 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the data thread"); 1864 goto error; 1865 } 1866 #else 1867 ret = pthread_create(&session->thread, NULL, daemon_thrdatamain, 1868 (void *) session); 1869 if (ret != 0) 1870 { 1871 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1872 ret, "Error creating the data thread"); 1873 goto error; 1874 } 1875 #endif 1876 session->have_thread = 1; 1877 1878 // Check if all the data has been read; if not, discard the data in excess 1879 if (rpcapd_discard(pars->sockctrl, plen) == -1) 1880 goto fatal_error; 1881 1882 *sessionp = session; 1883 return 0; 1884 1885 error: 1886 // 1887 // Not a fatal error, so send the client an error message and 1888 // keep serving client requests. 1889 // 1890 *sessionp = NULL; 1891 1892 if (addrinfo) 1893 freeaddrinfo(addrinfo); 1894 1895 if (session) 1896 { 1897 session_close(session); 1898 free(session); 1899 } 1900 1901 if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_STARTCAPTURE, 1902 errmsgbuf, errbuf) == -1) 1903 { 1904 // That failed; log a message and give up. 1905 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1906 return -1; 1907 } 1908 1909 // Check if all the data has been read; if not, discard the data in excess 1910 if (rpcapd_discard(pars->sockctrl, plen) == -1) 1911 { 1912 // Network error. 1913 return -1; 1914 } 1915 1916 return 0; 1917 1918 fatal_error: 1919 // 1920 // Fatal network error, so don't try to communicate with 1921 // the client, just give up. 1922 // 1923 *sessionp = NULL; 1924 1925 if (session) 1926 { 1927 session_close(session); 1928 free(session); 1929 } 1930 1931 return -1; 1932 } 1933 1934 static int 1935 daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars, 1936 struct session *session) 1937 { 1938 char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors 1939 struct rpcap_header header; 1940 1941 session_close(session); 1942 1943 rpcap_createhdr(&header, ver, RPCAP_MSG_ENDCAP_REPLY, 0, 0); 1944 1945 if (sock_send(pars->sockctrl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) 1946 { 1947 // That failed; log a message and give up. 1948 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 1949 return -1; 1950 } 1951 1952 return 0; 1953 } 1954 1955 // 1956 // We impose a limit on the filter program size, so that, on Windows, 1957 // where there's only one server process with multiple threads, it's 1958 // harder to eat all the server address space by sending larger filter 1959 // programs. (This isn't an issue on UN*X, where there are multiple 1960 // server processes, one per client connection.) 1961 // 1962 // We pick a value that limits each filter to 64K; that value is twice 1963 // the in-kernel limit for Linux and 16 times the in-kernel limit for 1964 // *BSD and macOS. 1965 // 1966 // It also prevents an overflow on 32-bit platforms when calculating 1967 // the total size of the filter program. (It's not an issue on 64-bit 1968 // platforms with a 64-bit size_t, as the filter size is 32 bits.) 1969 // 1970 #define RPCAP_BPF_MAXINSNS 8192 1971 1972 static int 1973 daemon_unpackapplyfilter(SOCKET sockctrl, struct session *session, uint32 *plenp, char *errmsgbuf) 1974 { 1975 int status; 1976 struct rpcap_filter filter; 1977 struct rpcap_filterbpf_insn insn; 1978 struct bpf_insn *bf_insn; 1979 struct bpf_program bf_prog; 1980 unsigned int i; 1981 1982 status = rpcapd_recv(sockctrl, (char *) &filter, 1983 sizeof(struct rpcap_filter), plenp, errmsgbuf); 1984 if (status == -1) 1985 { 1986 return -1; 1987 } 1988 if (status == -2) 1989 { 1990 return -2; 1991 } 1992 1993 bf_prog.bf_len = ntohl(filter.nitems); 1994 1995 if (ntohs(filter.filtertype) != RPCAP_UPDATEFILTER_BPF) 1996 { 1997 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Only BPF/NPF filters are currently supported"); 1998 return -2; 1999 } 2000 2001 if (bf_prog.bf_len > RPCAP_BPF_MAXINSNS) 2002 { 2003 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, 2004 "Filter program is larger than the maximum size of %u instructions", 2005 RPCAP_BPF_MAXINSNS); 2006 return -2; 2007 } 2008 bf_insn = (struct bpf_insn *) malloc (sizeof(struct bpf_insn) * bf_prog.bf_len); 2009 if (bf_insn == NULL) 2010 { 2011 pcap_fmt_errmsg_for_errno(errmsgbuf, PCAP_ERRBUF_SIZE, 2012 errno, "malloc() failed"); 2013 return -2; 2014 } 2015 2016 bf_prog.bf_insns = bf_insn; 2017 2018 for (i = 0; i < bf_prog.bf_len; i++) 2019 { 2020 status = rpcapd_recv(sockctrl, (char *) &insn, 2021 sizeof(struct rpcap_filterbpf_insn), plenp, errmsgbuf); 2022 if (status == -1) 2023 { 2024 return -1; 2025 } 2026 if (status == -2) 2027 { 2028 return -2; 2029 } 2030 2031 bf_insn->code = ntohs(insn.code); 2032 bf_insn->jf = insn.jf; 2033 bf_insn->jt = insn.jt; 2034 bf_insn->k = ntohl(insn.k); 2035 2036 bf_insn++; 2037 } 2038 2039 if (bpf_validate(bf_prog.bf_insns, bf_prog.bf_len) == 0) 2040 { 2041 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "The filter contains bogus instructions"); 2042 return -2; 2043 } 2044 2045 if (pcap_setfilter(session->fp, &bf_prog)) 2046 { 2047 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "RPCAP error: %s", pcap_geterr(session->fp)); 2048 return -2; 2049 } 2050 2051 return 0; 2052 } 2053 2054 static int 2055 daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars, 2056 struct session *session, uint32 plen) 2057 { 2058 char errbuf[PCAP_ERRBUF_SIZE]; 2059 char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client 2060 int ret; // status of daemon_unpackapplyfilter() 2061 struct rpcap_header header; // keeps the answer to the updatefilter command 2062 2063 ret = daemon_unpackapplyfilter(pars->sockctrl, session, &plen, errmsgbuf); 2064 if (ret == -1) 2065 { 2066 // Fatal error. A message has been logged; just give up. 2067 return -1; 2068 } 2069 if (ret == -2) 2070 { 2071 // Non-fatal error. Send an error reply to the client. 2072 goto error; 2073 } 2074 2075 // Check if all the data has been read; if not, discard the data in excess 2076 if (rpcapd_discard(pars->sockctrl, plen) == -1) 2077 { 2078 // Network error. 2079 return -1; 2080 } 2081 2082 // A response is needed, otherwise the other host does not know that everything went well 2083 rpcap_createhdr(&header, ver, RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0); 2084 2085 if (sock_send(pars->sockctrl, (char *) &header, sizeof (struct rpcap_header), pcap_geterr(session->fp), PCAP_ERRBUF_SIZE)) 2086 { 2087 // That failed; log a messsage and give up. 2088 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 2089 return -1; 2090 } 2091 2092 return 0; 2093 2094 error: 2095 if (rpcapd_discard(pars->sockctrl, plen) == -1) 2096 { 2097 return -1; 2098 } 2099 rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_UPDATEFILTER, 2100 errmsgbuf, NULL); 2101 2102 return 0; 2103 } 2104 2105 /*! 2106 \brief Received the sampling parameters from remote host and it stores in the pcap_t structure. 2107 */ 2108 static int 2109 daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, 2110 struct rpcap_sampling *samp_param) 2111 { 2112 char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors 2113 char errmsgbuf[PCAP_ERRBUF_SIZE]; 2114 struct rpcap_header header; 2115 struct rpcap_sampling rpcap_samp; 2116 int status; 2117 2118 status = rpcapd_recv(pars->sockctrl, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf); 2119 if (status == -1) 2120 { 2121 return -1; 2122 } 2123 if (status == -2) 2124 { 2125 goto error; 2126 } 2127 2128 // Save these settings in the pcap_t 2129 samp_param->method = rpcap_samp.method; 2130 samp_param->value = ntohl(rpcap_samp.value); 2131 2132 // A response is needed, otherwise the other host does not know that everything went well 2133 rpcap_createhdr(&header, ver, RPCAP_MSG_SETSAMPLING_REPLY, 0, 0); 2134 2135 if (sock_send(pars->sockctrl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) 2136 { 2137 // That failed; log a messsage and give up. 2138 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 2139 return -1; 2140 } 2141 2142 if (rpcapd_discard(pars->sockctrl, plen) == -1) 2143 { 2144 return -1; 2145 } 2146 2147 return 0; 2148 2149 error: 2150 if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_SETSAMPLING, 2151 errmsgbuf, errbuf) == -1) 2152 { 2153 // That failed; log a message and give up. 2154 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 2155 return -1; 2156 } 2157 2158 // Check if all the data has been read; if not, discard the data in excess 2159 if (rpcapd_discard(pars->sockctrl, plen) == -1) 2160 { 2161 return -1; 2162 } 2163 2164 return 0; 2165 } 2166 2167 static int 2168 daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, 2169 struct session *session, uint32 plen, struct pcap_stat *stats, 2170 unsigned int svrcapt) 2171 { 2172 char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors 2173 char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client 2174 char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered 2175 int sendbufidx = 0; // index which keeps the number of bytes currently buffered 2176 struct rpcap_stats *netstats; // statistics sent on the network 2177 2178 // Checks that the header does not contain other data; if so, discard it 2179 if (rpcapd_discard(pars->sockctrl, plen) == -1) 2180 { 2181 // Network error. 2182 return -1; 2183 } 2184 2185 if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, 2186 &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 2187 goto error; 2188 2189 rpcap_createhdr((struct rpcap_header *) sendbuf, ver, 2190 RPCAP_MSG_STATS_REPLY, 0, (uint16) sizeof(struct rpcap_stats)); 2191 2192 netstats = (struct rpcap_stats *) &sendbuf[sendbufidx]; 2193 2194 if (sock_bufferize(NULL, sizeof(struct rpcap_stats), NULL, 2195 &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) 2196 goto error; 2197 2198 if (session && session->fp) 2199 { 2200 if (pcap_stats(session->fp, stats) == -1) 2201 { 2202 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s", pcap_geterr(session->fp)); 2203 goto error; 2204 } 2205 2206 netstats->ifdrop = htonl(stats->ps_ifdrop); 2207 netstats->ifrecv = htonl(stats->ps_recv); 2208 netstats->krnldrop = htonl(stats->ps_drop); 2209 netstats->svrcapt = htonl(session->TotCapt); 2210 } 2211 else 2212 { 2213 // We have to keep compatibility with old applications, 2214 // which ask for statistics also when the capture has 2215 // already stopped. 2216 netstats->ifdrop = htonl(stats->ps_ifdrop); 2217 netstats->ifrecv = htonl(stats->ps_recv); 2218 netstats->krnldrop = htonl(stats->ps_drop); 2219 netstats->svrcapt = htonl(svrcapt); 2220 } 2221 2222 // Send the packet 2223 if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) 2224 { 2225 rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); 2226 return -1; 2227 } 2228 2229 return 0; 2230 2231 error: 2232 rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_GETSTATS, 2233 errmsgbuf, NULL); 2234 return 0; 2235 } 2236 2237 #ifdef _WIN32 2238 static unsigned __stdcall 2239 #else 2240 static void * 2241 #endif 2242 daemon_thrdatamain(void *ptr) 2243 { 2244 char errbuf[PCAP_ERRBUF_SIZE + 1]; // error buffer 2245 struct session *session; // pointer to the struct session for this session 2246 int retval; // general variable used to keep the return value of other functions 2247 struct rpcap_pkthdr *net_pkt_header;// header of the packet 2248 struct pcap_pkthdr *pkt_header; // pointer to the buffer that contains the header of the current packet 2249 u_char *pkt_data; // pointer to the buffer that contains the current packet 2250 size_t sendbufsize; // size for the send buffer 2251 char *sendbuf; // temporary buffer in which data to be sent is buffered 2252 int sendbufidx; // index which keeps the number of bytes currently buffered 2253 int status; 2254 #ifndef _WIN32 2255 sigset_t sigusr1; // signal set with just SIGUSR1 2256 #endif 2257 2258 session = (struct session *) ptr; 2259 2260 session->TotCapt = 0; // counter which is incremented each time a packet is received 2261 2262 // Initialize errbuf 2263 memset(errbuf, 0, sizeof(errbuf)); 2264 2265 // 2266 // We need a buffer large enough to hold a buffer large enough 2267 // for a maximum-size packet for this pcap_t. 2268 // 2269 if (pcap_snapshot(session->fp) < 0) 2270 { 2271 // 2272 // The snapshot length is negative. 2273 // This "should not happen". 2274 // 2275 rpcapd_log(LOGPRIO_ERROR, 2276 "Unable to allocate the buffer for this child thread: snapshot length of %d is negative", 2277 pcap_snapshot(session->fp)); 2278 sendbuf = NULL; // we can't allocate a buffer, so nothing to free 2279 goto error; 2280 } 2281 // 2282 // size_t is unsigned, and the result of pcap_snapshot() is signed; 2283 // on no platform that we support is int larger than size_t. 2284 // This means that, unless the extra information we prepend to 2285 // a maximum-sized packet is impossibly large, the sum of the 2286 // snapshot length and the size of that extra information will 2287 // fit in a size_t. 2288 // 2289 // So we don't need to make sure that sendbufsize will overflow. 2290 // 2291 sendbufsize = sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr) + pcap_snapshot(session->fp); 2292 sendbuf = (char *) malloc (sendbufsize); 2293 if (sendbuf == NULL) 2294 { 2295 rpcapd_log(LOGPRIO_ERROR, 2296 "Unable to allocate the buffer for this child thread"); 2297 goto error; 2298 } 2299 2300 #ifndef _WIN32 2301 // 2302 // Set the signal set to include just SIGUSR1, and block that 2303 // signal; we only want it unblocked when we're reading 2304 // packets - we dn't want any other system calls, such as 2305 // ones being used to send to the client or to log messages, 2306 // to be interrupted. 2307 // 2308 sigemptyset(&sigusr1); 2309 sigaddset(&sigusr1, SIGUSR1); 2310 pthread_sigmask(SIG_BLOCK, &sigusr1, NULL); 2311 #endif 2312 2313 // Retrieve the packets 2314 for (;;) 2315 { 2316 #ifndef _WIN32 2317 // 2318 // Unblock SIGUSR1 while we might be waiting for packets. 2319 // 2320 pthread_sigmask(SIG_UNBLOCK, &sigusr1, NULL); 2321 #endif 2322 retval = pcap_next_ex(session->fp, &pkt_header, (const u_char **) &pkt_data); // cast to avoid a compiler warning 2323 #ifndef _WIN32 2324 // 2325 // Now block it again. 2326 // 2327 pthread_sigmask(SIG_BLOCK, &sigusr1, NULL); 2328 #endif 2329 if (retval < 0) 2330 break; // error 2331 if (retval == 0) // Read timeout elapsed 2332 continue; 2333 2334 sendbufidx = 0; 2335 2336 // Bufferize the general header 2337 if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, 2338 &sendbufidx, sendbufsize, SOCKBUF_CHECKONLY, errbuf, 2339 PCAP_ERRBUF_SIZE) == -1) 2340 { 2341 rpcapd_log(LOGPRIO_ERROR, 2342 "sock_bufferize() error sending packet message: %s", 2343 errbuf); 2344 goto error; 2345 } 2346 2347 rpcap_createhdr((struct rpcap_header *) sendbuf, 2348 session->protocol_version, RPCAP_MSG_PACKET, 0, 2349 (uint16) (sizeof(struct rpcap_pkthdr) + pkt_header->caplen)); 2350 2351 net_pkt_header = (struct rpcap_pkthdr *) &sendbuf[sendbufidx]; 2352 2353 // Bufferize the pkt header 2354 if (sock_bufferize(NULL, sizeof(struct rpcap_pkthdr), NULL, 2355 &sendbufidx, sendbufsize, SOCKBUF_CHECKONLY, errbuf, 2356 PCAP_ERRBUF_SIZE) == -1) 2357 { 2358 rpcapd_log(LOGPRIO_ERROR, 2359 "sock_bufferize() error sending packet message: %s", 2360 errbuf); 2361 goto error; 2362 } 2363 2364 net_pkt_header->caplen = htonl(pkt_header->caplen); 2365 net_pkt_header->len = htonl(pkt_header->len); 2366 net_pkt_header->npkt = htonl(++(session->TotCapt)); 2367 net_pkt_header->timestamp_sec = htonl(pkt_header->ts.tv_sec); 2368 net_pkt_header->timestamp_usec = htonl(pkt_header->ts.tv_usec); 2369 2370 // Bufferize the pkt data 2371 if (sock_bufferize((char *) pkt_data, pkt_header->caplen, 2372 sendbuf, &sendbufidx, sendbufsize, SOCKBUF_BUFFERIZE, 2373 errbuf, PCAP_ERRBUF_SIZE) == -1) 2374 { 2375 rpcapd_log(LOGPRIO_ERROR, 2376 "sock_bufferize() error sending packet message: %s", 2377 errbuf); 2378 goto error; 2379 } 2380 2381 // Send the packet 2382 // If the client dropped the connection, don't report an 2383 // error, just quit. 2384 status = sock_send(session->sockdata, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE); 2385 if (status < 0) 2386 { 2387 if (status == -1) 2388 { 2389 // 2390 // Error other than "client closed the 2391 // connection out from under us"; report 2392 // it. 2393 // 2394 rpcapd_log(LOGPRIO_ERROR, 2395 "Send of packet to client failed: %s", 2396 errbuf); 2397 } 2398 2399 // 2400 // Give up in either case. 2401 // 2402 goto error; 2403 } 2404 } 2405 2406 if (retval < 0 && retval != PCAP_ERROR_BREAK) 2407 { 2408 // 2409 // Failed with an error other than "we were told to break 2410 // out of the loop". 2411 // 2412 // The latter just means that the client told us to stop 2413 // capturing, so there's no error to report. 2414 // 2415 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error reading the packets: %s", pcap_geterr(session->fp)); 2416 rpcap_senderror(session->sockctrl, session->protocol_version, 2417 PCAP_ERR_READEX, errbuf, NULL); 2418 } 2419 2420 error: 2421 // 2422 // The main thread will clean up the session structure. 2423 // 2424 free(sendbuf); 2425 2426 return 0; 2427 } 2428 2429 #ifndef _WIN32 2430 // 2431 // Do-nothing handler for SIGUSR1; the sole purpose of SIGUSR1 is to 2432 // interrupt the data thread if it's blocked in a system call waiting 2433 // for packets to arrive. 2434 // 2435 static void noop_handler(int sign _U_) 2436 { 2437 } 2438 #endif 2439 2440 /*! 2441 \brief It serializes a network address. 2442 2443 It accepts a 'sockaddr_storage' structure as input, and it converts it appropriately into a format 2444 that can be used to be sent on the network. Basically, it applies all the hton() 2445 conversion required to the input variable. 2446 2447 \param sockaddrin a 'sockaddr_storage' pointer to the variable that has to be 2448 serialized. This variable can be both a 'sockaddr_in' and 'sockaddr_in6'. 2449 2450 \param sockaddrout an 'rpcap_sockaddr' pointer to the variable that will contain 2451 the serialized data. This variable has to be allocated by the user. 2452 2453 \warning This function supports only AF_INET and AF_INET6 address families. 2454 */ 2455 static void 2456 daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout) 2457 { 2458 memset(sockaddrout, 0, sizeof(struct sockaddr_storage)); 2459 2460 // There can be the case in which the sockaddrin is not available 2461 if (sockaddrin == NULL) return; 2462 2463 // Warning: we support only AF_INET and AF_INET6 2464 switch (sockaddrin->ss_family) 2465 { 2466 case AF_INET: 2467 { 2468 struct sockaddr_in *sockaddrin_ipv4; 2469 struct rpcap_sockaddr_in *sockaddrout_ipv4; 2470 2471 sockaddrin_ipv4 = (struct sockaddr_in *) sockaddrin; 2472 sockaddrout_ipv4 = (struct rpcap_sockaddr_in *) sockaddrout; 2473 sockaddrout_ipv4->family = htons(RPCAP_AF_INET); 2474 sockaddrout_ipv4->port = htons(sockaddrin_ipv4->sin_port); 2475 memcpy(&sockaddrout_ipv4->addr, &sockaddrin_ipv4->sin_addr, sizeof(sockaddrout_ipv4->addr)); 2476 memset(sockaddrout_ipv4->zero, 0, sizeof(sockaddrout_ipv4->zero)); 2477 break; 2478 } 2479 2480 #ifdef AF_INET6 2481 case AF_INET6: 2482 { 2483 struct sockaddr_in6 *sockaddrin_ipv6; 2484 struct rpcap_sockaddr_in6 *sockaddrout_ipv6; 2485 2486 sockaddrin_ipv6 = (struct sockaddr_in6 *) sockaddrin; 2487 sockaddrout_ipv6 = (struct rpcap_sockaddr_in6 *) sockaddrout; 2488 sockaddrout_ipv6->family = htons(RPCAP_AF_INET6); 2489 sockaddrout_ipv6->port = htons(sockaddrin_ipv6->sin6_port); 2490 sockaddrout_ipv6->flowinfo = htonl(sockaddrin_ipv6->sin6_flowinfo); 2491 memcpy(&sockaddrout_ipv6->addr, &sockaddrin_ipv6->sin6_addr, sizeof(sockaddrout_ipv6->addr)); 2492 sockaddrout_ipv6->scope_id = htonl(sockaddrin_ipv6->sin6_scope_id); 2493 break; 2494 } 2495 #endif 2496 } 2497 } 2498 2499 2500 /*! 2501 \brief Suspends a thread for secs seconds. 2502 */ 2503 void sleep_secs(int secs) 2504 { 2505 #ifdef _WIN32 2506 Sleep(secs*1000); 2507 #else 2508 unsigned secs_remaining; 2509 2510 if (secs <= 0) 2511 return; 2512 secs_remaining = secs; 2513 while (secs_remaining != 0) 2514 secs_remaining = sleep(secs_remaining); 2515 #endif 2516 } 2517 2518 /* 2519 * Read the header of a message. 2520 */ 2521 static int 2522 rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp) 2523 { 2524 int nread; 2525 char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors 2526 2527 nread = sock_recv(sock, (char *) headerp, sizeof(struct rpcap_header), 2528 SOCK_RECEIVEALL_YES|SOCK_EOF_ISNT_ERROR, errbuf, PCAP_ERRBUF_SIZE); 2529 if (nread == -1) 2530 { 2531 // Network error. 2532 rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); 2533 return -1; 2534 } 2535 if (nread == 0) 2536 { 2537 // Immediate EOF; that's treated like a close message. 2538 return -2; 2539 } 2540 headerp->plen = ntohl(headerp->plen); 2541 return 0; 2542 } 2543 2544 /* 2545 * Read data from a message. 2546 * If we're trying to read more data that remains, puts an error 2547 * message into errmsgbuf and returns -2. Otherwise, tries to read 2548 * the data and, if that succeeds, subtracts the amount read from 2549 * the number of bytes of data that remains. 2550 * Returns 0 on success, logs a message and returns -1 on a network 2551 * error. 2552 */ 2553 static int 2554 rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf) 2555 { 2556 int nread; 2557 char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors 2558 2559 if (toread > *plen) 2560 { 2561 // Tell the client and continue. 2562 pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message payload is too short"); 2563 return -2; 2564 } 2565 nread = sock_recv(sock, buffer, toread, 2566 SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE); 2567 if (nread == -1) 2568 { 2569 rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); 2570 return -1; 2571 } 2572 *plen -= nread; 2573 return 0; 2574 } 2575 2576 /* 2577 * Discard data from a connection. 2578 * Mostly used to discard wrong-sized messages. 2579 * Returns 0 on success, logs a message and returns -1 on a network 2580 * error. 2581 */ 2582 static int 2583 rpcapd_discard(SOCKET sock, uint32 len) 2584 { 2585 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed 2586 2587 if (len != 0) 2588 { 2589 if (sock_discard(sock, len, errbuf, PCAP_ERRBUF_SIZE) == -1) 2590 { 2591 // Network error. 2592 rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); 2593 return -1; 2594 } 2595 } 2596 return 0; 2597 } 2598 2599 // 2600 // Shut down any packet-capture thread associated with the session, 2601 // close the SSL handle for the data socket if we have one, close 2602 // the data socket if we have one, and close the underlying packet 2603 // capture handle if we have one. 2604 // 2605 // We do not, of course, touch the controlling socket that's also 2606 // copied into the session, as the service loop might still use it. 2607 // 2608 static void session_close(struct session *session) 2609 { 2610 if (session->have_thread) 2611 { 2612 // 2613 // Tell the data connection thread main capture loop to 2614 // break out of that loop. 2615 // 2616 // This may be sufficient to wake up a blocked thread, 2617 // but it's not guaranteed to be sufficient. 2618 // 2619 pcap_breakloop(session->fp); 2620 2621 #ifdef _WIN32 2622 // 2623 // Set the event on which a read would block, so that, 2624 // if it's currently blocked waiting for packets to 2625 // arrive, it'll wake up, so it can see the "break 2626 // out of the loop" indication. (pcap_breakloop() 2627 // might do this, but older versions don't. Setting 2628 // it twice should, at worst, cause an extra wakeup, 2629 // which shouldn't be a problem.) 2630 // 2631 // XXX - what about modules other than NPF? 2632 // 2633 SetEvent(pcap_getevent(session->fp)); 2634 2635 // 2636 // Wait for the thread to exit, so we don't close 2637 // sockets out from under it. 2638 // 2639 // XXX - have a timeout, so we don't wait forever? 2640 // 2641 WaitForSingleObject(session->thread, INFINITE); 2642 2643 // 2644 // Release the thread handle, as we're done with 2645 // it. 2646 // 2647 CloseHandle(session->thread); 2648 session->have_thread = 0; 2649 session->thread = INVALID_HANDLE_VALUE; 2650 #else 2651 // 2652 // Send a SIGUSR1 signal to the thread, so that, if 2653 // it's currently blocked waiting for packets to arrive, 2654 // it'll wake up (we've turned off SA_RESTART for 2655 // SIGUSR1, so that the system call in which it's blocked 2656 // should return EINTR rather than restarting). 2657 // 2658 pthread_kill(session->thread, SIGUSR1); 2659 2660 // 2661 // Wait for the thread to exit, so we don't close 2662 // sockets out from under it. 2663 // 2664 // XXX - have a timeout, so we don't wait forever? 2665 // 2666 pthread_join(session->thread, NULL); 2667 session->have_thread = 0; 2668 memset(&session->thread, 0, sizeof(session->thread)); 2669 #endif 2670 } 2671 2672 if (session->sockdata != INVALID_SOCKET) 2673 { 2674 sock_close(session->sockdata, NULL, 0); 2675 session->sockdata = INVALID_SOCKET; 2676 } 2677 2678 if (session->fp) 2679 { 2680 pcap_close(session->fp); 2681 session->fp = NULL; 2682 } 2683 } 2684 2685 // 2686 // Check whether a capture source string is a URL or not. 2687 // This includes URLs that refer to a local device; a scheme, followed 2688 // by ://, followed by *another* scheme and ://, is just silly, and 2689 // anybody who supplies that will get an error. 2690 // 2691 static int 2692 is_url(const char *source) 2693 { 2694 char *colonp; 2695 2696 /* 2697 * RFC 3986 says: 2698 * 2699 * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 2700 * 2701 * hier-part = "//" authority path-abempty 2702 * / path-absolute 2703 * / path-rootless 2704 * / path-empty 2705 * 2706 * authority = [ userinfo "@" ] host [ ":" port ] 2707 * 2708 * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) 2709 * 2710 * Step 1: look for the ":" at the end of the scheme. 2711 * A colon in the source is *NOT* sufficient to indicate that 2712 * this is a URL, as interface names on some platforms might 2713 * include colons (e.g., I think some Solaris interfaces 2714 * might). 2715 */ 2716 colonp = strchr(source, ':'); 2717 if (colonp == NULL) 2718 { 2719 /* 2720 * The source is the device to open. It's not a URL. 2721 */ 2722 return (0); 2723 } 2724 2725 /* 2726 * All schemes must have "//" after them, i.e. we only support 2727 * hier-part = "//" authority path-abempty, not 2728 * hier-part = path-absolute 2729 * hier-part = path-rootless 2730 * hier-part = path-empty 2731 * 2732 * We need that in order to distinguish between a local device 2733 * name that happens to contain a colon and a URI. 2734 */ 2735 if (strncmp(colonp + 1, "//", 2) != 0) 2736 { 2737 /* 2738 * The source is the device to open. It's not a URL. 2739 */ 2740 return (0); 2741 } 2742 2743 /* 2744 * It's a URL. 2745 */ 2746 return (1); 2747 } 2748