|
43 | 43 | #include <stdarg.h> /* for functions with variable number of arguments */ |
44 | 44 | #include <errno.h> /* for the errno variable */ |
45 | 45 | #include <limits.h> /* for INT_MAX */ |
| 46 | + |
| 47 | +#ifndef _WIN32 |
| 48 | + #include <netinet/tcp.h> /* for TCP_KEEP* */ |
| 49 | +#endif |
| 50 | + |
46 | 51 | #include "sockutils.h" |
47 | 52 | #include "pcap-int.h" |
48 | 53 | #include "rpcap-protocol.h" |
@@ -3536,3 +3541,46 @@ static int rpcap_read_packet_msg(struct pcap_rpcap const *rp, pcap_t *p, size_t |
3536 | 3541 | p->cc = cc; |
3537 | 3542 | return 0; |
3538 | 3543 | } |
| 3544 | + |
| 3545 | +/* |
| 3546 | + * Set the keepalives parameters on the control socket. |
| 3547 | + * An rpcap-based application may detect more rapidly a network error. |
| 3548 | + * |
| 3549 | + * It may not be necessary to set them on the data socket as it may use UDP. |
| 3550 | + * See pcap_read_nocb_remote for the select logic that will take into |
| 3551 | + * account the error on the control socket. |
| 3552 | + */ |
| 3553 | +int |
| 3554 | +pcap_set_control_keepalive(pcap_t *p, int enable, int keepcnt, int keepidle, int keepintvl) |
| 3555 | +{ |
| 3556 | + struct pcap_rpcap *pr = p->priv; /* structure used when doing a remote live capture */ |
| 3557 | + |
| 3558 | + if (setsockopt(pr->rmt_sockctrl, SOL_SOCKET, SO_KEEPALIVE, (char *)&enable, sizeof(enable)) < 0) |
| 3559 | + { |
| 3560 | + sock_geterror("setsockopt(): ", p->errbuf, PCAP_ERRBUF_SIZE); |
| 3561 | + return -1; |
| 3562 | + } |
| 3563 | + |
| 3564 | + /* when SO_KEEPALIVE isn't active, the following options aren't used */ |
| 3565 | + if (!enable) |
| 3566 | + return 0; |
| 3567 | + |
| 3568 | +#if defined(TCP_KEEPCNT) && defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) |
| 3569 | + if (setsockopt(pr->rmt_sockctrl, IPPROTO_TCP, TCP_KEEPCNT, (char *)&keepcnt, sizeof(keepcnt)) < 0 || |
| 3570 | + setsockopt(pr->rmt_sockctrl, IPPROTO_TCP, TCP_KEEPIDLE, (char *)&keepidle, sizeof(keepidle)) < 0 || |
| 3571 | + setsockopt(pr->rmt_sockctrl, IPPROTO_TCP, TCP_KEEPINTVL, (char *)&keepintvl, sizeof(keepintvl)) < 0) |
| 3572 | + { |
| 3573 | + sock_geterror("setsockopt(): ", p->errbuf, PCAP_ERRBUF_SIZE); |
| 3574 | + return -1; |
| 3575 | + } |
| 3576 | +#else |
| 3577 | + if (keepcnt || keepidle || keepintvl) |
| 3578 | + { |
| 3579 | + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
| 3580 | + "TCP_KEEPCNT, TCP_KEEPIDLE or TCP_KEEPINTVL not supported on this platform"); |
| 3581 | + return -1; |
| 3582 | + } |
| 3583 | +#endif |
| 3584 | + |
| 3585 | + return 0; |
| 3586 | +} |
0 commit comments