Merge pull request #811 in FS/freeswitch from ~ALEXANDR.DUBOVIKOV_GMAIL.COM/freeswitch:feature/FS-9078-hepv2-and-hepv3-support to master
* commit '981b528c48a44e0e775f6c8dec8e91ce9a01f252': FS-9078 added hepv2 and hepv3 support
This commit is contained in:
commit
e06053c678
|
@ -5,6 +5,15 @@
|
|||
<!-- <param name="auto-restart" value="false"/> -->
|
||||
<param name="debug-presence" value="0"/>
|
||||
<!-- <param name="capture-server" value="udp:homer.domain.com:5060"/> -->
|
||||
|
||||
<!--
|
||||
the new format for HEPv2/v3 and capture ID
|
||||
|
||||
protocol:host:port;hep=2;capture_id=200;
|
||||
|
||||
-->
|
||||
|
||||
<!-- <param name="capture-server" value="udp:homer.domain.com:5060;hep=3;capture_id=100"/> -->
|
||||
</global_settings>
|
||||
|
||||
<!--
|
||||
|
|
|
@ -1 +1 @@
|
|||
Wed Sep 9 12:25:38 CDT 2015
|
||||
Mon Apr 18 10:41:03 CEST 2016
|
||||
|
|
|
@ -130,6 +130,13 @@ struct hep_iphdr{
|
|||
struct in_addr hp_dst; /* source and dest address */
|
||||
};
|
||||
|
||||
/* HEPv2 */
|
||||
struct hep_timehdr{
|
||||
uint32_t tv_sec; /* seconds */
|
||||
uint32_t tv_usec; /* useconds */
|
||||
uint16_t captid; /* Capture ID node */
|
||||
};
|
||||
|
||||
#if SU_HAVE_IN6
|
||||
struct hep_ip6hdr {
|
||||
struct in6_addr hp6_src; /* source address */
|
||||
|
@ -137,6 +144,86 @@ struct hep_ip6hdr {
|
|||
};
|
||||
#endif
|
||||
|
||||
/* HEPv3 types */
|
||||
struct hep_chunk {
|
||||
uint16_t vendor_id;
|
||||
uint16_t type_id;
|
||||
uint16_t length;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_chunk hep_chunk_t;
|
||||
|
||||
struct hep_chunk_uint8 {
|
||||
hep_chunk_t chunk;
|
||||
uint8_t data;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_chunk_uint8 hep_chunk_uint8_t;
|
||||
|
||||
struct hep_chunk_uint16 {
|
||||
hep_chunk_t chunk;
|
||||
uint16_t data;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_chunk_uint16 hep_chunk_uint16_t;
|
||||
|
||||
struct hep_chunk_uint32 {
|
||||
hep_chunk_t chunk;
|
||||
uint32_t data;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_chunk_uint32 hep_chunk_uint32_t;
|
||||
|
||||
struct hep_chunk_str {
|
||||
hep_chunk_t chunk;
|
||||
char *data;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_chunk_str hep_chunk_str_t;
|
||||
|
||||
struct hep_chunk_ip4 {
|
||||
hep_chunk_t chunk;
|
||||
struct in_addr data;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_chunk_ip4 hep_chunk_ip4_t;
|
||||
|
||||
struct hep_chunk_ip6 {
|
||||
hep_chunk_t chunk;
|
||||
struct in6_addr data;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_chunk_ip6 hep_chunk_ip6_t;
|
||||
|
||||
struct hep_chunk_payload {
|
||||
hep_chunk_t chunk;
|
||||
char *data;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_chunk_payload hep_chunk_payload_t;
|
||||
|
||||
struct hep_ctrl {
|
||||
char id[4];
|
||||
uint16_t length;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_ctrl hep_ctrl_t;
|
||||
|
||||
struct hep_generic {
|
||||
hep_ctrl_t header;
|
||||
hep_chunk_uint8_t ip_family;
|
||||
hep_chunk_uint8_t ip_proto;
|
||||
hep_chunk_uint16_t src_port;
|
||||
hep_chunk_uint16_t dst_port;
|
||||
hep_chunk_uint32_t time_sec;
|
||||
hep_chunk_uint32_t time_usec;
|
||||
hep_chunk_uint8_t proto_t;
|
||||
hep_chunk_uint32_t capt_id;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct hep_generic hep_generic_t;
|
||||
|
||||
|
||||
/** Maximum size when streaming. */
|
||||
#define MSG_SSIZE_MAX (USIZE_MAX)
|
||||
|
||||
|
|
|
@ -306,6 +306,8 @@ struct tport_master {
|
|||
su_socket_t mr_capt_sock;
|
||||
char *mr_capt_name; /**< Servername for capturing received/sent data */
|
||||
tport_primary_t *mr_primaries; /**< List of primary contacts */
|
||||
unsigned mr_prot_ver; /* hep version */
|
||||
unsigned mr_agent_id; /* agent version */
|
||||
|
||||
tport_params_t mr_params[1];
|
||||
|
||||
|
@ -486,6 +488,12 @@ void tport_dump_iovec(tport_t const *self, msg_t *msg,
|
|||
void tport_capt_msg(tport_t const *self, msg_t *msg, size_t n,
|
||||
su_iovec_t const iov[], size_t iovused, char const *what);
|
||||
|
||||
int tport_capt_msg_hepv2(tport_t const *self, msg_t *msg, size_t n,
|
||||
su_iovec_t const iov[], size_t iovused, char const *what, char **buffer);
|
||||
|
||||
int tport_capt_msg_hepv3(tport_t const *self, msg_t *msg, size_t n,
|
||||
su_iovec_t const iov[], size_t iovused, char const *what, char **buffer);
|
||||
|
||||
int tport_tcp_ping(tport_t *self, su_time_t now);
|
||||
int tport_tcp_pong(tport_t *self);
|
||||
|
||||
|
|
|
@ -143,7 +143,9 @@ int tport_open_log(tport_master_t *mr, tagi_t *tags)
|
|||
char *captname, *p, *host_s;
|
||||
char port[10];
|
||||
su_addrinfo_t *ai = NULL, hints[1] = {{ 0 }};
|
||||
unsigned len =0;
|
||||
unsigned len =0, iport = 0;
|
||||
|
||||
|
||||
|
||||
if (mr->mr_capt_name && mr->mr_capt_sock && strcmp(capt, mr->mr_capt_name) == 0)
|
||||
return n;
|
||||
|
@ -173,17 +175,60 @@ int tport_open_log(tport_master_t *mr, tagi_t *tags)
|
|||
/*the address contains a port number*/
|
||||
*p = '\0';
|
||||
p++;
|
||||
|
||||
iport = atoi(p);
|
||||
|
||||
if (atoi(p) <1024 || atoi(p)>65536)
|
||||
if (iport <1024 || iport >65536)
|
||||
{
|
||||
su_log("invalid port number; must be in [1024,65536]\n");
|
||||
return n;
|
||||
}
|
||||
|
||||
strncpy(port, p, sizeof(port));
|
||||
|
||||
*p = '\0';
|
||||
|
||||
snprintf(port, sizeof(port), "%d", iport);
|
||||
|
||||
/* default values for capture protocol and agent id */
|
||||
mr->mr_prot_ver = 3;
|
||||
mr->mr_agent_id = 200;
|
||||
|
||||
/* get all params */
|
||||
while(p)
|
||||
{
|
||||
/* check ; in the URL */
|
||||
if( (p = strchr(p+1, ';')) == 0 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
p++;
|
||||
|
||||
SU_DEBUG_7(("events HEP RRR DATA [%s]\n", p));
|
||||
|
||||
if(strncmp(p, "hep=",4) == 0) {
|
||||
p+=4;
|
||||
mr->mr_prot_ver = atoi(p);
|
||||
/* hepv3 come later */
|
||||
if (mr->mr_prot_ver < 1 || mr->mr_prot_ver > 3)
|
||||
{
|
||||
su_log("invalid hep version number; must be in [1-3]\n");
|
||||
mr->mr_prot_ver = 3;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else if(strncmp(p, "capture_id=", 11) == 0) {
|
||||
p+=11;
|
||||
if((mr->mr_agent_id = atoi(p)) == 0)
|
||||
{
|
||||
mr->mr_agent_id = 200;
|
||||
su_log("invalid capture id number; must be uint32 \n");
|
||||
return n;
|
||||
}
|
||||
}
|
||||
else {
|
||||
su_log("unsupported capture param\n");
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if we have [] */
|
||||
if (host_s[0] == '[') {
|
||||
len = strlen(host_s + 1) - 1;
|
||||
|
@ -211,7 +256,6 @@ int tport_open_log(tport_master_t *mr, tagi_t *tags)
|
|||
hints->ai_socktype = SOCK_DGRAM;
|
||||
hints->ai_protocol = IPPROTO_UDP;
|
||||
|
||||
|
||||
if (su_getaddrinfo(host_s, port, hints, &ai)) {
|
||||
su_perror("capture: su_getaddrinfo()");
|
||||
return n;
|
||||
|
@ -357,18 +401,72 @@ void tport_capt_msg(tport_t const *self, msg_t *msg, size_t n,
|
|||
{
|
||||
|
||||
int buflen = 0, error;
|
||||
char* buffer = NULL;
|
||||
tport_master_t *mr;
|
||||
|
||||
assert(self);
|
||||
|
||||
mr = self->tp_master;
|
||||
|
||||
/* If we don't have socket, go out */
|
||||
if (!mr->mr_capt_sock) {
|
||||
su_log("error: capture socket is not open\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(mr->mr_prot_ver)
|
||||
{
|
||||
|
||||
case 3:
|
||||
buflen = tport_capt_msg_hepv3(self, msg, n, iov, iovused, what, &buffer);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
buflen = tport_capt_msg_hepv2(self, msg, n, iov, iovused, what, &buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
su_log("error: unsupported hep version\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if(buflen > 0) {
|
||||
/* check if we have error i.e. capture server is down */
|
||||
if ((error = su_soerror(mr->mr_capt_sock))) {
|
||||
su_perror("error: tport_logging: capture socket error");
|
||||
goto done;
|
||||
}
|
||||
|
||||
su_send(mr->mr_capt_sock, buffer, buflen, 0);
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
/* Now we release it */
|
||||
if(buffer) free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
/** Capture the data from the iovec */
|
||||
int tport_capt_msg_hepv2 (tport_t const *self, msg_t *msg, size_t n,
|
||||
su_iovec_t const iov[], size_t iovused, char const *what, char **buffer)
|
||||
{
|
||||
|
||||
int buflen = 0;
|
||||
su_sockaddr_t const *su, *su_self;
|
||||
struct hep_hdr hep_header;
|
||||
struct hep_timehdr hep_time = {0};
|
||||
su_time_t now;
|
||||
#if __sun__
|
||||
struct hep_iphdr hep_ipheader = {{{{0}}}};
|
||||
#else
|
||||
struct hep_iphdr hep_ipheader = {{0}};
|
||||
struct hep_iphdr hep_ipheader = {{0}};
|
||||
#endif
|
||||
#if SU_HAVE_IN6
|
||||
struct hep_ip6hdr hep_ip6header = {{{{0}}}};
|
||||
#endif
|
||||
int eth_frame_len = 8000;
|
||||
char* buffer;
|
||||
int eth_frame_len = 16000;
|
||||
size_t i, dst = 0;
|
||||
tport_master_t *mr;
|
||||
|
||||
|
@ -382,14 +480,14 @@ void tport_capt_msg(tport_t const *self, msg_t *msg, size_t n,
|
|||
/* If we don't have socket, go out */
|
||||
if (!mr->mr_capt_sock) {
|
||||
su_log("error: capture socket is not open\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*buffer for ethernet frame*/
|
||||
buffer = (void*)malloc(eth_frame_len);
|
||||
*buffer = (void*)malloc(eth_frame_len);
|
||||
|
||||
/* VOIP Header */
|
||||
hep_header.hp_v = 1;
|
||||
hep_header.hp_v = mr->mr_prot_ver;
|
||||
hep_header.hp_f = su->su_family;
|
||||
/* Header Length */
|
||||
hep_header.hp_l = sizeof(struct hep_hdr);
|
||||
|
@ -423,19 +521,22 @@ void tport_capt_msg(tport_t const *self, msg_t *msg, size_t n,
|
|||
hep_header.hp_dport = dst ? su->su_port : su_self->su_port;
|
||||
hep_header.hp_sport = dst ? su_self->su_port : su->su_port;
|
||||
|
||||
if (hep_header.hp_v == 2){
|
||||
hep_header.hp_l += sizeof(struct hep_timehdr);
|
||||
}
|
||||
|
||||
/* Copy hepheader */
|
||||
memset(buffer, '\0', eth_frame_len);
|
||||
memcpy(buffer, &hep_header, sizeof(struct hep_hdr));
|
||||
memset(*buffer, '\0', eth_frame_len);
|
||||
memcpy(*buffer, &hep_header, sizeof(struct hep_hdr));
|
||||
buflen = sizeof(struct hep_hdr);
|
||||
|
||||
if(su->su_family == AF_INET) {
|
||||
memcpy(buffer + buflen, &hep_ipheader, sizeof(struct hep_iphdr));
|
||||
memcpy(*buffer + buflen, &hep_ipheader, sizeof(struct hep_iphdr));
|
||||
buflen += sizeof(struct hep_iphdr);
|
||||
}
|
||||
#if SU_HAVE_IN6
|
||||
else if(su->su_family == AF_INET6) {
|
||||
memcpy(buffer+buflen, &hep_ip6header, sizeof(struct hep_ip6hdr));
|
||||
memcpy(*buffer+buflen, &hep_ip6header, sizeof(struct hep_ip6hdr));
|
||||
buflen += sizeof(struct hep_ip6hdr);
|
||||
}
|
||||
#endif
|
||||
|
@ -444,6 +545,23 @@ void tport_capt_msg(tport_t const *self, msg_t *msg, size_t n,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* copy time header */
|
||||
if (hep_header.hp_v == 2) {
|
||||
/* now */
|
||||
now = su_now();
|
||||
/* should check for ifdef HAVE_LOCALTIME_R instead -_- */
|
||||
#if defined(HAVE_GETTIMEOFDAY) || defined(HAVE_CLOCK_MONOTONIC)
|
||||
hep_time.tv_sec = (now.tv_sec - SU_TIME_EPOCH); /* see su_time0.c 'now' is not really 'now', so we decrease it by SU_TIME_EPOCH */
|
||||
#else
|
||||
hep_time.tv_sec = now.tv_sec;
|
||||
#endif
|
||||
hep_time.tv_usec = now.tv_usec;
|
||||
|
||||
hep_time.captid = mr->mr_agent_id;
|
||||
memcpy((void*)*buffer+buflen, &hep_time, sizeof(struct hep_timehdr));
|
||||
buflen += sizeof(struct hep_timehdr);
|
||||
}
|
||||
|
||||
for (i = 0; i < iovused && n > 0; i++) {
|
||||
size_t len = iov[i].mv_len;
|
||||
if (len > n)
|
||||
|
@ -452,26 +570,251 @@ void tport_capt_msg(tport_t const *self, msg_t *msg, size_t n,
|
|||
if((buflen + len) > eth_frame_len)
|
||||
break;
|
||||
|
||||
memcpy(buffer + buflen , (void*)iov[i].mv_base, len);
|
||||
memcpy(*buffer + buflen , (void*)iov[i].mv_base, len);
|
||||
buflen +=len;
|
||||
n -= len;
|
||||
}
|
||||
|
||||
/* check if we have error i.e. capture server is down */
|
||||
if ((error = su_soerror(mr->mr_capt_sock))) {
|
||||
su_perror("error: tport_logging: capture socket error");
|
||||
goto done;
|
||||
}
|
||||
|
||||
su_send(mr->mr_capt_sock, buffer, buflen, 0);
|
||||
|
||||
return buflen;
|
||||
|
||||
done:
|
||||
/* Now we release it */
|
||||
if(buffer) free(buffer);
|
||||
return;
|
||||
if(*buffer) {
|
||||
free(*buffer);
|
||||
*buffer = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Capture the data from the iovec */
|
||||
int tport_capt_msg_hepv3 (tport_t const *self, msg_t *msg, size_t n,
|
||||
su_iovec_t const iov[], size_t iovused, char const *what, char **buffer)
|
||||
{
|
||||
|
||||
su_sockaddr_t const *su, *su_self;
|
||||
struct hep_generic *hg=NULL;
|
||||
unsigned int buflen=0, iplen=0,tlen=0, payload_len = 0;
|
||||
su_time_t now;
|
||||
hep_chunk_ip4_t src_ip4, dst_ip4;
|
||||
hep_chunk_t payload_chunk;
|
||||
int orig_n = 0;
|
||||
|
||||
#if SU_HAVE_IN6
|
||||
hep_chunk_ip6_t src_ip6, dst_ip6;
|
||||
#endif
|
||||
|
||||
int eth_frame_len = 16000;
|
||||
size_t i, dst = 0;
|
||||
tport_master_t *mr;
|
||||
|
||||
assert(self); assert(msg);
|
||||
|
||||
su = msg_addr(msg);
|
||||
su_self = self->tp_pri->pri_primary->tp_addr;
|
||||
|
||||
mr = self->tp_master;
|
||||
|
||||
/* If we don't have socket, go out */
|
||||
if (!mr->mr_capt_sock) {
|
||||
su_log("error: capture socket is not open\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*buffer for ethernet frame*/
|
||||
|
||||
hg = malloc(sizeof(struct hep_generic));
|
||||
memset(hg, 0, sizeof(struct hep_generic));
|
||||
|
||||
/* header set */
|
||||
memcpy(hg->header.id, "\x48\x45\x50\x33", 4);
|
||||
|
||||
/* IP proto */
|
||||
hg->ip_family.chunk.vendor_id = htons(0x0000);
|
||||
hg->ip_family.chunk.type_id = htons(0x0001);
|
||||
hg->ip_family.data = su->su_family;
|
||||
hg->ip_family.chunk.length = htons(sizeof(hg->ip_family));
|
||||
|
||||
/* PROTOCOL */
|
||||
if(strcmp(self->tp_name->tpn_proto, "tcp") == 0) hg->ip_proto.data = IPPROTO_TCP;
|
||||
else if(strcmp(self->tp_name->tpn_proto, "tls") == 0) hg->ip_proto.data = IPPROTO_IDP; /* FAKE*/
|
||||
else if(strcmp(self->tp_name->tpn_proto, "sctp") == 0) hg->ip_proto.data = IPPROTO_SCTP;
|
||||
else if(strcmp(self->tp_name->tpn_proto, "ws") == 0) hg->ip_proto.data = IPPROTO_TCP;
|
||||
else if(strcmp(self->tp_name->tpn_proto, "wss") == 0) hg->ip_proto.data = IPPROTO_TCP;
|
||||
else hg->ip_proto.data = IPPROTO_UDP; /* DEFAULT UDP */
|
||||
|
||||
/* Proto ID */
|
||||
hg->ip_proto.chunk.vendor_id = htons(0x0000);
|
||||
hg->ip_proto.chunk.type_id = htons(0x0002);
|
||||
hg->ip_proto.chunk.length = htons(sizeof(hg->ip_proto));
|
||||
|
||||
/* Check destination */
|
||||
if(strncmp("sent", what, 4) == 0) dst = 1;
|
||||
|
||||
/* copy destination and source IPs*/
|
||||
if(su->su_family == AF_INET) {
|
||||
|
||||
/* SRC IP */
|
||||
src_ip4.chunk.vendor_id = htons(0x0000);
|
||||
src_ip4.chunk.type_id = htons(0x0003);
|
||||
memcpy(dst ? &dst_ip4.data : &src_ip4.data, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
src_ip4.chunk.length = htons(sizeof(src_ip4));
|
||||
|
||||
/* DST IP */
|
||||
dst_ip4.chunk.vendor_id = htons(0x0000);
|
||||
dst_ip4.chunk.type_id = htons(0x0004);
|
||||
memcpy(dst ? &src_ip4.data : &dst_ip4.data, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
dst_ip4.chunk.length = htons(sizeof(dst_ip4));
|
||||
|
||||
iplen = sizeof(dst_ip4) + sizeof(src_ip4);
|
||||
}
|
||||
#if SU_HAVE_IN6
|
||||
else if(su->su_family == AF_INET6) {
|
||||
|
||||
/* SRC IPv6 */
|
||||
src_ip6.chunk.vendor_id = htons(0x0000);
|
||||
src_ip6.chunk.type_id = htons(0x0005);
|
||||
memcpy(dst ? &dst_ip6.data : &src_ip6.data, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
src_ip6.chunk.length = htons(sizeof(src_ip6));
|
||||
|
||||
/* DST IPv6 */
|
||||
dst_ip6.chunk.vendor_id = htons(0x0000);
|
||||
dst_ip6.chunk.type_id = htons(0x0006);
|
||||
memcpy(dst ? &src_ip6.data : &dst_ip6.data, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
dst_ip6.chunk.length = htons(sizeof(dst_ip6));
|
||||
|
||||
iplen = sizeof(dst_ip6) + sizeof(src_ip6);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
su_perror("error: tport_logging hepv3: capture: unsupported protocol family");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* SRC PORT */
|
||||
hg->src_port.chunk.vendor_id = htons(0x0000);
|
||||
hg->src_port.chunk.type_id = htons(0x0007);
|
||||
hg->src_port.data = dst ? htons(su->su_port) : htons(su_self->su_port);
|
||||
hg->src_port.chunk.length = htons(sizeof(hg->src_port));
|
||||
|
||||
/* DST PORT */
|
||||
hg->dst_port.chunk.vendor_id = htons(0x0000);
|
||||
hg->dst_port.chunk.type_id = htons(0x0008);
|
||||
hg->dst_port.data = dst ? htons(su_self->su_port) : htons(su->su_port);
|
||||
hg->dst_port.chunk.length = htons(sizeof(hg->dst_port));
|
||||
|
||||
|
||||
/* TIMESTAMP SEC */
|
||||
hg->time_sec.chunk.vendor_id = htons(0x0000);
|
||||
hg->time_sec.chunk.type_id = htons(0x0009);
|
||||
hg->time_sec.chunk.length = htons(sizeof(hg->time_sec));
|
||||
|
||||
now = su_now();
|
||||
/* should check for ifdef HAVE_LOCALTIME_R instead -_- */
|
||||
#if defined(HAVE_GETTIMEOFDAY) || defined(HAVE_CLOCK_MONOTONIC)
|
||||
hg->time_sec.data = htonl(now.tv_sec - SU_TIME_EPOCH); /* see su_time0.c 'now' is not really 'now', so we decrease it by SU_TIME_EPOCH */
|
||||
#else
|
||||
hg->time_sec.data = htonl(now.tv_sec);
|
||||
#endif
|
||||
|
||||
/* TIMESTAMP USEC */
|
||||
hg->time_usec.chunk.vendor_id = htons(0x0000);
|
||||
hg->time_usec.chunk.type_id = htons(0x000a);
|
||||
hg->time_usec.data = htonl(now.tv_usec);
|
||||
hg->time_usec.chunk.length = htons(sizeof(hg->time_usec));
|
||||
|
||||
/* Protocol TYPE */
|
||||
hg->proto_t.chunk.vendor_id = htons(0x0000);
|
||||
hg->proto_t.chunk.type_id = htons(0x000b);
|
||||
hg->proto_t.data = 0x001; //SIP
|
||||
hg->proto_t.chunk.length = htons(sizeof(hg->proto_t));
|
||||
|
||||
/* Capture ID */
|
||||
hg->capt_id.chunk.vendor_id = htons(0x0000);
|
||||
hg->capt_id.chunk.type_id = htons(0x000c);
|
||||
hg->capt_id.data = htons(mr->mr_agent_id);
|
||||
hg->capt_id.chunk.length = htons(sizeof(hg->capt_id));
|
||||
|
||||
|
||||
/* Payload caclulation */
|
||||
orig_n = n;
|
||||
for (i = 0; i < iovused && n > 0; i++) {
|
||||
size_t len = iov[i].mv_len;
|
||||
if (len > n) len = n;
|
||||
if((payload_len + len) > eth_frame_len) break;
|
||||
payload_len +=len;
|
||||
n -= len;
|
||||
}
|
||||
/* restore n */
|
||||
n = orig_n;
|
||||
|
||||
/* Payload */
|
||||
payload_chunk.vendor_id = htons(0x0000);
|
||||
payload_chunk.type_id = htons(0x000f);
|
||||
payload_chunk.length = htons(sizeof(payload_chunk) + payload_len);
|
||||
|
||||
tlen = sizeof(struct hep_generic) + payload_len + iplen + sizeof(hep_chunk_t);
|
||||
|
||||
/* total */
|
||||
hg->header.length = htons(tlen);
|
||||
|
||||
*buffer = (void*)malloc(tlen);
|
||||
|
||||
if (*buffer==NULL){
|
||||
su_perror("error: tport_logging hepv3: no memory for buffer");
|
||||
goto done;
|
||||
}
|
||||
|
||||
memcpy((void*) *buffer, hg, sizeof(struct hep_generic));
|
||||
buflen = sizeof(struct hep_generic);
|
||||
|
||||
/* IPv4 */
|
||||
if(su->su_family == AF_INET) {
|
||||
/* SRC IP */
|
||||
memcpy((void*) *buffer+buflen, &src_ip4, sizeof(struct hep_chunk_ip4));
|
||||
buflen += sizeof(struct hep_chunk_ip4);
|
||||
|
||||
memcpy((void*) *buffer+buflen, &dst_ip4, sizeof(struct hep_chunk_ip4));
|
||||
buflen += sizeof(struct hep_chunk_ip4);
|
||||
}
|
||||
#if SU_HAVE_IN6
|
||||
/* IPv6 */
|
||||
else if(su->su_family == AF_INET6) {
|
||||
/* SRC IPv6 */
|
||||
memcpy((void*) *buffer+buflen, &src_ip4, sizeof(struct hep_chunk_ip6));
|
||||
buflen += sizeof(struct hep_chunk_ip6);
|
||||
|
||||
memcpy((void*) *buffer+buflen, &dst_ip6, sizeof(struct hep_chunk_ip6));
|
||||
buflen += sizeof(struct hep_chunk_ip6);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* PAYLOAD CHUNK */
|
||||
memcpy((void*) *buffer+buflen, &payload_chunk, sizeof(struct hep_chunk));
|
||||
buflen += sizeof(struct hep_chunk);
|
||||
|
||||
/* PAYLOAD */
|
||||
for (i = 0; i < iovused && n > 0; i++) {
|
||||
size_t len = iov[i].mv_len;
|
||||
if (len > n) len = n;
|
||||
/* if the packet too big for us */
|
||||
if((buflen + len) > eth_frame_len)
|
||||
break;
|
||||
|
||||
memcpy(*buffer + buflen , (void*)iov[i].mv_base, len);
|
||||
buflen +=len;
|
||||
n -= len;
|
||||
}
|
||||
|
||||
return buflen;
|
||||
|
||||
done:
|
||||
/* Now we release it */
|
||||
if(hg) free(hg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Log the message. */
|
||||
void tport_log_msg(tport_t *self, msg_t *msg,
|
||||
char const *what, char const *via,
|
||||
|
|
Loading…
Reference in New Issue