diff options
Diffstat (limited to 'rpcapd/daemon.c')
-rw-r--r-- | rpcapd/daemon.c | 166 |
1 files changed, 94 insertions, 72 deletions
diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c index 362f4b9b..0f3dd271 100644 --- a/rpcapd/daemon.c +++ b/rpcapd/daemon.c @@ -113,7 +113,7 @@ struct session { SOCKET sockctrl; SOCKET sockdata; SSL *ctrl_ssl, *data_ssl; // optional SSL handlers for sockctrl and sockdata. - uint8 protocol_version; + uint8_t protocol_version; pcap_t *fp; unsigned int TotCapt; int have_thread; @@ -125,31 +125,31 @@ struct session { }; // Locally defined functions -static int daemon_msg_err(SOCKET sockctrl, SSL *, uint32 plen); -static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen); +static int daemon_msg_err(SOCKET sockctrl, SSL *, uint32_t plen); +static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32_t plen); static int daemon_AuthUserPwd(char *username, char *password, char *errbuf); -static int daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, - uint32 plen); +static int daemon_msg_findallif_req(uint8_t ver, struct daemon_slpars *pars, + uint32_t plen); -static int daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, - uint32 plen, char *source, size_t sourcelen); -static int daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, - uint32 plen, char *source, struct session **sessionp, +static int daemon_msg_open_req(uint8_t ver, struct daemon_slpars *pars, + uint32_t plen, char *source, size_t sourcelen); +static int daemon_msg_startcap_req(uint8_t ver, struct daemon_slpars *pars, + uint32_t plen, char *source, char *data_port, struct session **sessionp, struct rpcap_sampling *samp_param, int uses_ssl); -static int daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars, +static int daemon_msg_endcap_req(uint8_t ver, struct daemon_slpars *pars, struct session *session); -static int daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars, - struct session *session, uint32 plen); -static int daemon_unpackapplyfilter(SOCKET sockctrl, SSL *, struct session *session, uint32 *plenp, char *errbuf); +static int daemon_msg_updatefilter_req(uint8_t ver, struct daemon_slpars *pars, + struct session *session, uint32_t plen); +static int daemon_unpackapplyfilter(SOCKET sockctrl, SSL *, struct session *session, uint32_t *plenp, char *errbuf); -static int daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, - struct session *session, uint32 plen, struct pcap_stat *stats, +static int daemon_msg_stats_req(uint8_t ver, struct daemon_slpars *pars, + struct session *session, uint32_t plen, struct pcap_stat *stats, unsigned int svrcapt); -static int daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, - uint32 plen, struct rpcap_sampling *samp_param); +static int daemon_msg_setsampling_req(uint8_t ver, struct daemon_slpars *pars, + uint32_t plen, struct rpcap_sampling *samp_param); static void daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout); #ifdef _WIN32 @@ -160,8 +160,8 @@ static void noop_handler(int sign); #endif static int rpcapd_recv_msg_header(SOCKET sock, SSL *, struct rpcap_header *headerp); -static int rpcapd_recv(SOCKET sock, SSL *, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf); -static int rpcapd_discard(SOCKET sock, SSL *, uint32 len); +static int rpcapd_recv(SOCKET sock, SSL *, char *buffer, size_t toread, uint32_t *plen, char *errmsgbuf); +static int rpcapd_discard(SOCKET sock, SSL *, uint32_t len); static void session_close(struct session *); // @@ -169,14 +169,14 @@ static void session_close(struct session *); // the client, in case we aren't doing TLS but they are. // struct tls_record_header { - uint8 type; // ContentType - will be 22, for Handshake - uint8 version_major; // TLS protocol major version - uint8 version_injor; // TLS protocol minor version + uint8_t type; // ContentType - will be 22, for Handshake + uint8_t version_major; // TLS protocol major version + uint8_t version_injor; // TLS protocol minor version // This is *not* aligned on a 2-byte boundary; we just // declare it as two bytes. Don't assume any particular // compiler's mechanism for saying "packed"! - uint8 length_hi; // Upper 8 bits of payload length - uint8 length_lo; // Low 8 bits of payload length + uint8_t length_hi; // Upper 8 bits of payload length + uint8_t length_lo; // Low 8 bits of payload length }; #define TLS_RECORD_HEADER_LEN 5 // Don't use sizeof in case it's padded @@ -188,8 +188,8 @@ struct tls_record_header { // TLS alert message. // struct tls_alert { - uint8 alert_level; - uint8 alert_description; + uint8_t alert_level; + uint8_t alert_description; }; #define TLS_ALERT_LEN 2 @@ -212,9 +212,9 @@ static int is_url(const char *source); int daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, - int nullAuthAllowed, int uses_ssl) + int nullAuthAllowed, char *data_port, int uses_ssl) { - uint8 first_octet; + uint8_t first_octet; struct tls_record_header tls_header; struct tls_alert tls_alert; struct daemon_slpars pars; // service loop parameters @@ -224,7 +224,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, SSL *ssl = NULL; int nrecv; struct rpcap_header header; // RPCAP message general header - uint32 plen; // payload length from header + uint32_t plen; // payload length from header int authenticated = 0; // 1 if the client has successfully authenticated char source[PCAP_BUF_SIZE+1]; // keeps the string that contains the interface to open int got_source = 0; // 1 if we've gotten the source from an open request @@ -449,7 +449,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, if (getpeername(pars.sockctrl, (struct sockaddr *)&from, &fromlen) == -1) { - sock_geterror("getpeername()", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getpeername() failed"); if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; @@ -523,7 +524,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, retval = select((int)pars.sockctrl + 1, &rfds, NULL, NULL, &tv); if (retval == -1) { - sock_geterror("select() failed", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "select() failed"); if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; @@ -763,7 +765,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, #endif if (retval == -1) { - sock_geterror("select() failed", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "select() failed"); if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) @@ -898,8 +901,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, } if (daemon_msg_startcap_req(header.ver, &pars, - plen, source, &session, &samp_param, - uses_ssl) == -1) + plen, source, data_port, &session, + &samp_param, uses_ssl) == -1) { // Fatal error; a message has // been logged, so just give up. @@ -1135,7 +1138,7 @@ end: * This handles the RPCAP_MSG_ERR message. */ static int -daemon_msg_err(SOCKET sockctrl, SSL *ssl, uint32 plen) +daemon_msg_err(SOCKET sockctrl, SSL *ssl, uint32_t plen) { char errbuf[PCAP_ERRBUF_SIZE]; char remote_errbuf[PCAP_ERRBUF_SIZE]; @@ -1214,7 +1217,7 @@ daemon_msg_err(SOCKET sockctrl, SSL *ssl, uint32 plen) * unrecoverable error or for the authentication failure. */ static int -daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) +daemon_msg_auth_req(struct daemon_slpars *pars, uint32_t plen) { char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client @@ -1258,7 +1261,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) case RPCAP_RMTAUTH_PWD: { char *username, *passwd; - uint32 usernamelen, passwdlen; + uint32_t usernamelen, passwdlen; usernamelen = ntohs(auth.slen1); username = (char *) malloc (usernamelen + 1); @@ -1368,11 +1371,16 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) goto error; // - // Indicate to our peer what versions we support. + // Indicate to our peer what versions we support and what our + // version of the byte-order magic is (which will tell the + // client whether our byte order differs from theirs, in which + // case they will need to byte-swap some fields in some + // link-layer types' headers). // memset(authreply, 0, sizeof(struct rpcap_authreply)); authreply->minvers = RPCAP_MIN_VERSION; authreply->maxvers = RPCAP_MAX_VERSION; + authreply->byte_order_magic = RPCAP_BYTE_ORDER_MAGIC; // Send the reply. if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) @@ -1590,10 +1598,10 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) sizeof (errmsgbuf)); \ goto error; \ } \ - replylen += (uint32)(itemlen) + replylen += (uint32_t)(itemlen) static int -daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) +daemon_msg_findallif_req(uint8_t ver, struct daemon_slpars *pars, uint32_t plen) { char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client @@ -1602,8 +1610,8 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) pcap_if_t *alldevs = NULL; // pointer to the header of the interface chain pcap_if_t *d; // temp pointer needed to scan the interface chain struct pcap_addr *address; // pcap structure that keeps a network address of an interface - uint32 replylen; // length of reply payload - uint16 nif = 0; // counts the number of interface listed + uint32_t replylen; // length of reply payload + uint16_t nif = 0; // counts the number of interface listed // Discard the rest of the message; there shouldn't be any payload. if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) @@ -1700,7 +1708,7 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) // send the interface list for (d = alldevs; d != NULL; d = d->next) { - uint16 lname, ldescr; + uint16_t lname, ldescr; // Note: the findalldevs_if entries are *not* neatly // aligned on 4-byte boundaries, because they're @@ -1719,11 +1727,11 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) * fit in 16 bits. */ if (d->description) - ldescr = (uint16) strlen(d->description); + ldescr = (uint16_t) strlen(d->description); else ldescr = 0; if (d->name) - lname = (uint16) strlen(d->name); + lname = (uint16_t) strlen(d->name); else lname = 0; @@ -1843,7 +1851,7 @@ error: to discard excess data in the message, if present) */ static int -daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, +daemon_msg_open_req(uint8_t ver, struct daemon_slpars *pars, uint32_t plen, char *source, size_t sourcelen) { char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors @@ -1882,7 +1890,7 @@ daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, // This is a fake open, since we do that only to get the needed parameters, then we close the device again if ((fp = pcap_open_live(source, 1500 /* fake snaplen */, - 0 /* no promis */, + 0 /* no promisc */, 1000 /* fake timeout */, errmsgbuf)) == NULL) goto error; @@ -1945,8 +1953,8 @@ error: to discard excess data in the message, if present) */ static int -daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, - char *source, struct session **sessionp, +daemon_msg_startcap_req(uint8_t ver, struct daemon_slpars *pars, uint32_t plen, + char *source, char *data_port, struct session **sessionp, struct rpcap_sampling *samp_param _U_, int uses_ssl) { char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors @@ -2054,7 +2062,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, saddrlen = sizeof(struct sockaddr_storage); if (getpeername(pars->sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) { - sock_geterror("getpeername()", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getpeername() failed"); goto error; } @@ -2071,32 +2080,43 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peerhost, sizeof(peerhost), NULL, 0, NI_NUMERICHOST)) { - sock_geterror("getnameinfo()", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getnameinfo() failed"); goto error; } if (sock_initaddress(peerhost, portdata, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) goto error; - if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) + if ((session->sockdata = sock_open(peerhost, addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) goto error; } else // Data connection is opened by the client toward the server { hints.ai_flags = AI_PASSIVE; - // Let's the server socket pick up a free network port for us - if (sock_initaddress(NULL, "0", &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) - goto error; + if (data_port[0] != '\0') + { + // Use the specified network port + if (sock_initaddress(NULL, data_port, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + } + else + { + // Make the server socket pick up a free network port for us + if (sock_initaddress(NULL, NULL, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) + goto error; + } - if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) + if ((session->sockdata = sock_open(NULL, addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) goto error; // get the complete sockaddr structure used in the data connection saddrlen = sizeof(struct sockaddr_storage); if (getsockname(session->sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1) { - sock_geterror("getsockname()", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getsockname() failed"); goto error; } @@ -2104,7 +2124,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL, 0, portdata, sizeof(portdata), NI_NUMERICSERV)) { - sock_geterror("getnameinfo()", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getnameinfo() failed"); goto error; } } @@ -2172,7 +2193,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, if (socktemp == INVALID_SOCKET) { - sock_geterror("accept()", errbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "accept() failed"); rpcapd_log(LOGPRIO_ERROR, "Accept of data connection failed: %s", errbuf); goto error; @@ -2278,7 +2300,7 @@ fatal_error: } static int -daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars, +daemon_msg_endcap_req(uint8_t ver, struct daemon_slpars *pars, struct session *session) { char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors @@ -2316,7 +2338,7 @@ daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars, #define RPCAP_BPF_MAXINSNS 8192 static int -daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session, uint32 *plenp, char *errmsgbuf) +daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session, uint32_t *plenp, char *errmsgbuf) { int status; struct rpcap_filter filter; @@ -2401,8 +2423,8 @@ daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session } static int -daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars, - struct session *session, uint32 plen) +daemon_msg_updatefilter_req(uint8_t ver, struct daemon_slpars *pars, + struct session *session, uint32_t plen) { char errbuf[PCAP_ERRBUF_SIZE]; char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client @@ -2455,7 +2477,7 @@ error: \brief Received the sampling parameters from remote host and it stores in the pcap_t structure. */ static int -daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, +daemon_msg_setsampling_req(uint8_t ver, struct daemon_slpars *pars, uint32_t plen, struct rpcap_sampling *samp_param) { char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors @@ -2514,8 +2536,8 @@ error: } static int -daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, - struct session *session, uint32 plen, struct pcap_stat *stats, +daemon_msg_stats_req(uint8_t ver, struct daemon_slpars *pars, + struct session *session, uint32_t plen, struct pcap_stat *stats, unsigned int svrcapt) { char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors @@ -2536,7 +2558,7 @@ daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, goto error; rpcap_createhdr((struct rpcap_header *) sendbuf, ver, - RPCAP_MSG_STATS_REPLY, 0, (uint16) sizeof(struct rpcap_stats)); + RPCAP_MSG_STATS_REPLY, 0, (uint16_t) sizeof(struct rpcap_stats)); netstats = (struct rpcap_stats *) &sendbuf[sendbufidx]; @@ -2709,7 +2731,7 @@ daemon_thrdatamain(void *ptr) rpcap_createhdr((struct rpcap_header *) sendbuf, session->protocol_version, RPCAP_MSG_PACKET, 0, - (uint16) (sizeof(struct rpcap_pkthdr) + pkt_header->caplen)); + (uint16_t) (sizeof(struct rpcap_pkthdr) + pkt_header->caplen)); net_pkt_header = (struct rpcap_pkthdr *) &sendbuf[sendbufidx]; @@ -2731,8 +2753,8 @@ daemon_thrdatamain(void *ptr) // This protocol needs to be updated with a new version // before 2038-01-19 03:14:07 UTC. // - net_pkt_header->timestamp_sec = htonl((uint32)pkt_header->ts.tv_sec); - net_pkt_header->timestamp_usec = htonl((uint32)pkt_header->ts.tv_usec); + net_pkt_header->timestamp_sec = htonl((uint32_t)pkt_header->ts.tv_sec); + net_pkt_header->timestamp_usec = htonl((uint32_t)pkt_header->ts.tv_usec); // Bufferize the pkt data if (sock_bufferize((char *) pkt_data, pkt_header->caplen, @@ -2927,7 +2949,7 @@ rpcapd_recv_msg_header(SOCKET sock, SSL *ssl, struct rpcap_header *headerp) * error. */ static int -rpcapd_recv(SOCKET sock, SSL *ssl, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf) +rpcapd_recv(SOCKET sock, SSL *ssl, char *buffer, size_t toread, uint32_t *plen, char *errmsgbuf) { int nread; char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors @@ -2956,7 +2978,7 @@ rpcapd_recv(SOCKET sock, SSL *ssl, char *buffer, size_t toread, uint32 *plen, ch * error. */ static int -rpcapd_discard(SOCKET sock, SSL *ssl, uint32 len) +rpcapd_discard(SOCKET sock, SSL *ssl, uint32_t len) { char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed |