CMConfigureInfo_t cmInfo;
} CAUtilConfig_t;
+#define MAX_IP_LENGTH 46
+
+typedef struct
+{
+ /* These 4 values are Kernel dependent and can be extracted only when Kernel is
+ built with enabling to monitor these values*/
+ u_int32_t tcpi_snd_nxt;
+ u_int32_t tcpi_rcv_nxt;
+ u_int32_t tcpi_rcv_wnd;
+ u_int8_t tcpi_rcv_wscale;
+ /*....*/
+ u_int8_t tcpi_src_addr[MAX_IP_LENGTH];
+ u_int32_t tcpi_src_port;
+ u_int8_t tcpi_dst_addr[MAX_IP_LENGTH];
+ u_int32_t tcpi_dst_port;
+ u_int32_t ip_version;
+ void* info;
+} TCPHeaderInfo;
+
+typedef struct
+{
+ u_int8_t tcpi_state;
+ u_int8_t tcpi_ca_state;
+ u_int8_t tcpi_retransmits;
+ u_int8_t tcpi_probes;
+ u_int8_t tcpi_backoff;
+ u_int8_t tcpi_options;
+ u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+
+ /* TCP Keep Alive Offload */
+ u_int32_t tcpi_snd_nxt;
+ u_int32_t tcpi_rcv_nxt;
+ u_int32_t tcpi_rcv_wnd;
+
+ u_int32_t tcpi_rto;
+ u_int32_t tcpi_ato;
+ u_int32_t tcpi_snd_mss;
+ u_int32_t tcpi_rcv_mss;
+
+ u_int32_t tcpi_unacked;
+ u_int32_t tcpi_sacked;
+ u_int32_t tcpi_lost;
+ u_int32_t tcpi_retrans;
+ u_int32_t tcpi_fackets;
+
+ /* Times. */
+ u_int32_t tcpi_last_data_sent;
+ u_int32_t tcpi_last_ack_sent;
+ u_int32_t tcpi_last_data_recv;
+ u_int32_t tcpi_last_ack_recv;
+
+ /* Metrics. */
+ u_int32_t tcpi_pmtu;
+ u_int32_t tcpi_rcv_ssthresh;
+ u_int32_t tcpi_rtt;
+ u_int32_t tcpi_rttvar;
+ u_int32_t tcpi_snd_ssthresh;
+ u_int32_t tcpi_snd_cwnd;
+ u_int32_t tcpi_advmss;
+ u_int32_t tcpi_reordering;
+ u_int32_t tcpi_rcv_rtt;
+ u_int32_t tcpi_rcv_space;
+ u_int32_t tcpi_total_retrans;
+} TCPInfo;
+
/**
* Callback function type for connection status changes delivery.
* @param[out] info Remote endpoint information.
CAResult_t CAUtilStartGattServer();
CAResult_t CAUtilStopGattServer();
+CAResult_t CAGetTCPIPHeader(CATransportAdapter_t adapter, int flag, TCPHeaderInfo* info);
#ifdef __cplusplus
} /* extern "C" */
*
******************************************************************/
+#include <netdb.h>
+#include <ifaddrs.h>
+#include <netinet/tcp.h>
+#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#include "caremotehandler.h"
#include "logger.h"
#include "oic_malloc.h"
+
#ifdef __WITH_TLS__
#include "ca_adapter_net_ssl.h"
#endif
#define CA_TCP_SELECT_TIMEOUT 10
+#define CA_IPV4_VERSION 4
+
+#define CA_IPV6_VERSION 6
/**
* Mutex to synchronize TCP adapter access.
*/
CAFreeTCPData(TCPData);
}
+void CAGetTCPLocalIP(CATransportFlags_t flag, char* localIP)
+{
+ //int targetPort;
+ char targetIP[MAX_IP_LENGTH];
+ memset(&targetIP, 0x00, sizeof(targetIP));
+ struct ifaddrs *ifp = NULL;
+ struct ifaddrs *ifa = NULL;
+
+ if (-1 == getifaddrs(&ifp)) {
+ return;
+ }
+
+ for (ifa = ifp; ifa; ifa = ifa->ifa_next)
+ {
+ if (!ifa->ifa_addr) {
+ continue;
+ }
+ int family = ifa->ifa_addr->sa_family;
+
+ if (CA_IPV6 & flag) {
+ if ((ifa->ifa_flags & IFF_LOOPBACK) || AF_INET6 != family) {
+ continue;
+ }
+ struct sockaddr_in6 *in = (struct sockaddr_in6*) ifa->ifa_addr;
+ inet_ntop(AF_INET6, &in->sin6_addr, targetIP, MAX_IP_LENGTH);
+ //targetPort = ntohs(in->sin6_port);
+ } else if (CA_IPV4 & flag) {
+ if ((ifa->ifa_flags & IFF_LOOPBACK) || AF_INET != family) {
+ continue;
+ }
+ struct sockaddr_in *in = (struct sockaddr_in*) ifa->ifa_addr;
+ inet_ntop(AF_INET, &in->sin_addr, targetIP, MAX_IP_LENGTH);
+ //targetPort = ntohs(in->sin_port);
+ }
+ break;
+ }
+
+ strncpy(localIP, targetIP, MAX_IP_LENGTH);
+ //*localport = targetPort;
+ OIC_LOG_V(DEBUG, TAG, "src_addr = %s", localIP);
+}
+
+int CAGetSocketInformation(u_int8_t* destIP, u_int32_t *destPort){
+
+ oc_mutex_lock(g_mutexAdapter);
+ uint32_t length = u_arraylist_length(caglobals.tcp.svrlist);
+ for (size_t i = 0; i < length; i++)
+ {
+ CATCPSessionInfo_t *svritem = (CATCPSessionInfo_t *) u_arraylist_get(
+ caglobals.tcp.svrlist, i);
+ if (!svritem)
+ {
+ continue;
+ }
+
+ if (svritem->state == CONNECTED)
+ {
+ strncpy((char *)destIP, svritem->sep.endpoint.addr, MAX_IP_LENGTH);
+ *destPort = svritem->sep.endpoint.port;
+ OIC_LOG_V(INFO, TAG, "Dest Ip : %s, Dest Port : %d", destIP, *destPort);
+ oc_mutex_unlock(g_mutexAdapter);
+ return svritem->fd;
+ }
+ }
+ oc_mutex_unlock(g_mutexAdapter);
+ return -1;
+}
+
+CAResult_t CAGetTCPIPHeaderInfo(CATransportFlags_t flag, TCPHeaderInfo* tcpHeaderInfo)
+{
+ CAResult_t res = CA_STATUS_OK;
+ VERIFY_NON_NULL(tcpHeaderInfo, TAG, "tcpHeaderInfo");
+
+ TCPInfo info;
+ int len = sizeof(info);
+
+ OIC_LOG_V(INFO, TAG, "Flags passed is = %d", flag);
+ int socket_fd;
+ //Get socketfd, destination ip and port.
+ socket_fd = CAGetSocketInformation(tcpHeaderInfo->tcpi_dst_addr, &(tcpHeaderInfo->tcpi_dst_port));
+ if(socket_fd == -1){
+ OIC_LOG(ERROR, TAG, "getsocket Failed");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(INFO, TAG, "Socket Interface is = %d", socket_fd);
+ OIC_LOG_V(INFO, TAG, "Port Number is = %d", tcpHeaderInfo->tcpi_dst_port);
+
+ if (getsockopt(socket_fd, SOL_TCP, TCP_INFO, (void *)&info, (socklen_t *)&len) == 0)
+ {
+ OIC_LOG(DEBUG, TAG, "getsockopt Success");
+ unsigned int source_port = 0;
+ struct sockaddr address;
+ socklen_t source_len = sizeof(address);;
+ char source_ip[MAX_IP_LENGTH];
+ bzero(&source_ip, MAX_IP_LENGTH);
+
+ // Get Local Ip and Port
+ if (CA_IPV6 & flag) {
+ struct sockaddr_in6 *sourceAddrInfo;
+ getsockname(socket_fd, &address, &source_len);
+ sourceAddrInfo = (struct sockaddr_in6*)&address;
+ inet_ntop(AF_INET6, &sourceAddrInfo->sin6_addr, source_ip, sizeof(source_ip));
+ source_port = ntohs(sourceAddrInfo->sin6_port);
+ tcpHeaderInfo->ip_version = CA_IPV6_VERSION;
+ } else if (CA_IPV4 & flag) {
+ struct sockaddr_in *sourceAddrInfo;
+ getsockname(socket_fd, &address, &source_len);
+ sourceAddrInfo = (struct sockaddr_in*)&address;
+ inet_ntop(AF_INET, &sourceAddrInfo->sin_addr, source_ip, sizeof(source_ip));
+ source_port = ntohs(sourceAddrInfo->sin_port);
+ tcpHeaderInfo->ip_version = CA_IPV4_VERSION;
+ }
+
+ //GET Local IP and port
+ strncpy((char *)tcpHeaderInfo->tcpi_src_addr, source_ip, MAX_IP_LENGTH);
+ tcpHeaderInfo->tcpi_src_port = source_port;
+ tcpHeaderInfo->tcpi_rcv_nxt = info.tcpi_rcv_nxt;
+ tcpHeaderInfo->tcpi_snd_nxt = info.tcpi_snd_nxt;
+ tcpHeaderInfo->tcpi_rcv_wnd = info.tcpi_rcv_wnd;
+ tcpHeaderInfo->tcpi_rcv_wscale = info.tcpi_rcv_wscale;
+ }
+ else {
+ OIC_LOG(INFO, TAG, "getsockopt Fail");
+ OIC_LOG_V(INFO, TAG, "getsockopt error %s", strerror(errno));
+ res = CA_SOCKET_OPERATION_FAILED;
+ }
+
+ OIC_LOG(INFO, TAG, "========tcpHeaderInfo=========");
+ OIC_LOG_V(INFO, TAG, "src_addr = %s", tcpHeaderInfo->tcpi_src_addr);
+ OIC_LOG_V(INFO, TAG, "src_port = %d", tcpHeaderInfo->tcpi_src_port);
+ OIC_LOG_V(INFO, TAG, "dst_addr = %s", tcpHeaderInfo->tcpi_dst_addr);
+ OIC_LOG_V(INFO, TAG, "dst_port = %d", tcpHeaderInfo->tcpi_dst_port);
+ OIC_LOG_V(INFO, TAG, "version = %d", tcpHeaderInfo->ip_version);
+ OIC_LOG_V(INFO, TAG, "seq_num = 0x%02x", tcpHeaderInfo->tcpi_snd_nxt);
+ OIC_LOG_V(INFO, TAG, "ack_num = 0x%02x", tcpHeaderInfo->tcpi_rcv_nxt);
+ OIC_LOG_V(INFO, TAG, "wnd = 0x%02x", tcpHeaderInfo->tcpi_rcv_wnd);
+ OIC_LOG_V(INFO, TAG, "wscale = %d", tcpHeaderInfo->tcpi_rcv_wscale);
+ OIC_LOG(INFO, TAG, "========================");
+
+ return res;
+}
+
#ifdef SINGLE_THREAD
size_t CAGetTotalLengthFromPacketHeader(const unsigned char *recvBuffer, size_t size)
{