Add hdr and tlv of nflog for pcap 58/195658/1
authorhyunuktak <hyunuk.tak@samsung.com>
Mon, 17 Dec 2018 05:45:47 +0000 (14:45 +0900)
committerhyunuktak <hyunuk.tak@samsung.com>
Mon, 17 Dec 2018 05:45:50 +0000 (14:45 +0900)
Change-Id: I99e01ab3262c4d0a002a35c7d1eeefdadb8c20fe
Signed-off-by: hyunuktak <hyunuk.tak@samsung.com>
packaging/stc-manager.spec
plugin/pcap/include/stc-plugin-pcap.h
plugin/pcap/stc-plugin-pcap.c

index eeb10ef..4f177eb 100644 (file)
@@ -1,6 +1,6 @@
 Name:       stc-manager
 Summary:    STC(Smart Traffic Control) manager
-Version:    0.0.85
+Version:    0.0.86
 Release:    0
 Group:      Network & Connectivity/Other
 License:    Apache-2.0
index d1747b2..aced8f9 100755 (executable)
@@ -26,6 +26,7 @@
 #include <signal.h>
 #include <errno.h>
 #include <pcap.h>
+#include <pcap/nflog.h>
 #include <arpa/inet.h>
 #include <net/ethernet.h>
 #include <net/if_arp.h>
 
 typedef struct {
        char *ifname;
+       char *nfname;
        int nflog_group;
        GThread *thread;
        pcap_t *handle;
+       int encap_type;
 } stc_pcap_data_s;
 
 typedef struct {
@@ -210,6 +213,9 @@ typedef struct udphdr          udp_t;
 #define SIZE_UDP_HEADER        sizeof(udp_t)
 #define SIZE_DNS_HEADER        sizeof(dns_t)
 
+#define SIZE_NFLOG_HDR         sizeof(nflog_hdr_t)
+#define SIZE_NFLOG_TLV         sizeof(nflog_tlv_t)
+
 #define IS_SRC_OR_DST_PORT(p) (source == (p) || dest == (p))
 
 typedef struct {
index 8785368..7921a1e 100755 (executable)
@@ -16,6 +16,9 @@
 
 #include "stc-plugin-pcap.h"
 
+#define ENCAPTYPE_ETHERNET  1
+#define ENCAPTYPE_NFLOG     141
+
 #define PCAP_IFNAME         "ifname"
 #define PCAP_NFLOG_GROUP    "nflog_group"
 #define PCAP_DEV_NAME       "dev"
 #define PCAP_DEV_NET        "net"
 #define PCAP_DEV_MASK       "mask"
 
+#define NFLOG_IFNAME        "nflog"
+
+typedef struct {
+       u_int32_t ts[4];
+} nflog_timestamp_s;
+
 //LCOV_EXCL_START
 static GHashTable *g_pcap_tables = NULL;
 static bool g_pcap_start_fm = false;
@@ -35,6 +44,7 @@ static void __pcap_data_free(gpointer value)
        g_thread_unref(data->thread);
 
        FREE(data->ifname);
+       FREE(data->nfname);
        FREE(data);
 }
 
@@ -108,10 +118,9 @@ static uint16_t __pcap_ntp_fraction_info(uint16_t f)
        return fraction;
 }
 
-static void __pcap_ntp_info(const u_char *packet)
+static void __pcap_ntp_info(const u_char **packet)
 {
-       ntp_t *ntp_h = (ntp_t *)(packet +
-               SIZE_ETHER_HEADER + SIZE_IP_HEADER + SIZE_UDP_HEADER);
+       ntp_t *ntp_h = (ntp_t *)*packet;
        char refid[BUFF_SIZE_ID];
        char reftime[BUFF_SIZE_TIME];
        char orgtime[BUFF_SIZE_TIME];
@@ -124,7 +133,7 @@ static void __pcap_ntp_info(const u_char *packet)
        __pcap_ntp_time_info(ntp_h->rectime.second, rectime);
        __pcap_ntp_time_info(ntp_h->xmttime.second, xmttime);
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Flags[0x%02x] Stratum[%u] Poll[%u:%us] Precision[%u] "
                        "Root delay[%u.%06us] Root dispersion[%u.%06us] Ref ID[%s]",
                        ntp_h->flags, ntp_h->stratum, ntp_h->poll,
@@ -135,7 +144,7 @@ static void __pcap_ntp_info(const u_char *packet)
                        __pcap_ntp_fraction_info(ntp_h->rootdisp.fraction),
                        refid);
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Reference[%s] Origin[%s] Receive[%s] Transmit[%s]",
                        reftime, orgtime, rectime, xmttime);
 }
@@ -233,7 +242,7 @@ static void __pcap_bootp_magic_info(uint32_t magic,
                char buf[BOOTP_MOPTION_LEN];
                uint8_t *opt = moption;
 
-               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+               if (STC_PCAP_LOG)
                        STC_LOGD("Magic cookie[DHCP]");
 
                while(len > 0) {
@@ -247,72 +256,72 @@ static void __pcap_bootp_magic_info(uint32_t magic,
                        case DHCP_TAG_SUBNET_MASK:
                                inet_ntop(AF_INET, (struct in_addr *)data,
                                        addr, BUFF_SIZE_IP);
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Subnet mask[%s]", addr);
                                break;
                        case DHCP_TAG_ROUTER:
                                inet_ntop(AF_INET, (struct in_addr *)data,
                                        addr, BUFF_SIZE_IP);
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Router[%s]", addr);
                                break;
                        case DHCP_TAG_DNS:
                                inet_ntop(AF_INET, (struct in_addr *)data,
                                        addr, BUFF_SIZE_IP);
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Domain name server[%s]", addr);
                                break;
                        case DHCP_TAG_HOST_NAME:
                                snprintf(buf, ((length < BOOTP_MOPTION_LEN) ?
                                                (length + 1) : BOOTP_MOPTION_LEN), "%s", (char *)data);
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Host name[%s]", buf);
                                break;
                        case DHCP_TAG_REQUESTED_IP:
                                inet_ntop(AF_INET, (struct in_addr *)data,
                                        addr, BUFF_SIZE_IP);
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Requested IP[%s]", addr);
                                break;
                        case DHCP_TAG_IP_LEASE_TIME:
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("IP address lease time[%us]",
                                                ntohl(*(uint32_t *)data));
                                break;
                        case DHCP_TAG_MSG_TYPE:
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("DHCP message type[%u:%s]", *data,
                                                __pcap_dhcp_msg_type_info(*data));
                                break;
                        case DHCP_TAG_SERVER_ID:
                                inet_ntop(AF_INET, (struct in_addr *)data,
                                        addr, BUFF_SIZE_IP);
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("DHCP server identifier[%s]", addr);
                                break;
                        case DHCP_TAG_MSG_SIZE:
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Maximum DHCP message size[%u]",
                                                ntohs(*(uint16_t *)data));
                                break;
                        case DHCP_TAG_CLIENT_ID:
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Client identifier HW type[0x%02x:%s]", *data,
                                                __pcap_dhcp_client_id_info(*data));
                                if (*data == DHCP_CLIENT_ID_ETHERNET) {
                                        g_strlcpy(host,
                                                ether_ntoa((const struct ether_addr *)&data[1]),
                                                sizeof(host));
-                                       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                                       if (STC_PCAP_LOG)
                                                STC_LOGD("Client identifier MAC[%s]", host);
                                }
                                break;
                        case DHCP_TAG_END:
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("End");
                                return;
                        default:
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Unknown[%u]", tag);
                                break;
                        }
@@ -342,18 +351,14 @@ static const char *__pcap_bootp_op_info(uint8_t op)
        return info;
 }
 
-static void __pcap_bootp_info(const u_char *packet)
+static void __pcap_bootp_info(const u_char **packet, u_int16_t len)
 {
-       udp_t *udp_h = (udp_t *)(packet
-               + SIZE_ETHER_HEADER + SIZE_IP_HEADER);
-       bootp_t *bootp_h = (bootp_t *)(packet +
-               SIZE_ETHER_HEADER + SIZE_IP_HEADER + SIZE_UDP_HEADER);
+       bootp_t *bootp_h = (bootp_t *)*packet;
        char ciaddr[BUFF_SIZE_IP];
        char yiaddr[BUFF_SIZE_IP];
        char siaddr[BUFF_SIZE_IP];
        char giaddr[BUFF_SIZE_IP];
        char chaddr[BUFF_SIZE_HOST];
-       u_int16_t len;
 
        inet_ntop(AF_INET, &bootp_h->ciaddr, ciaddr, BUFF_SIZE_IP);
        inet_ntop(AF_INET, &bootp_h->yiaddr, yiaddr, BUFF_SIZE_IP);
@@ -364,19 +369,18 @@ static void __pcap_bootp_info(const u_char *packet)
                ether_ntoa((const struct ether_addr *)bootp_h->chaddr),
                sizeof(chaddr));
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Message type[%u:%s] HW type[0x%02x] HW len[%u] Hops[%u] "
                        "Transaction ID[0x%08x] Seconds elapsed[%u] Flags[0x%04x]",
                        bootp_h->op, __pcap_bootp_op_info(bootp_h->op),
                        bootp_h->htype, bootp_h->hlen, bootp_h->hops,
                        ntohl(bootp_h->xid), ntohs(bootp_h->secs), ntohs(bootp_h->flags));
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Client[%s] Your(client)[%s] Next server[%s] "
                        "Relay agent[%s] Client MAC[%s]",
                        ciaddr, yiaddr, siaddr, giaddr, chaddr);
 
-       len = ntohs(udp_h->len);
        __pcap_bootp_magic_info(bootp_h->magic, bootp_h->moption, len);
 }
 
@@ -468,14 +472,9 @@ static uint8_t * __pcap_dns_name_info(uint8_t *dns_h,
        return (uint8_t *)nxt;
 }
 
-static void __pcap_dns_data_info(const u_char *packet)
+static void __pcap_dns_data_info(const u_char **packet, dns_t *dns_h)
 {
-       dns_t *dns_h = (dns_t *)(packet +
-               SIZE_ETHER_HEADER + SIZE_IP_HEADER +
-               SIZE_UDP_HEADER);
-       uint8_t *data = (uint8_t *)(packet +
-               SIZE_ETHER_HEADER + SIZE_IP_HEADER +
-               SIZE_UDP_HEADER + SIZE_DNS_HEADER);
+       uint8_t *data = (uint8_t *)*packet;
        uint16_t qdcount = ntohs(dns_h->questions);
        uint16_t ancount = ntohs(dns_h->answerRR);
        int i = 0;
@@ -486,7 +485,7 @@ static void __pcap_dns_data_info(const u_char *packet)
                uint16_t class;
 
                if (i == 0) {
-                       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                       if (STC_PCAP_LOG)
                                STC_LOGD("[Queries]");
                }
 
@@ -497,7 +496,7 @@ static void __pcap_dns_data_info(const u_char *packet)
                type = ntohs(*(uint16_t *)&data[0]);
                class = ntohs(*(uint16_t *)&data[2]);
 
-               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+               if (STC_PCAP_LOG)
                        STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s]",
                                name, type, __pcap_dns_type_info(type),
                                class, __pcap_dns_class_info(class));
@@ -515,7 +514,7 @@ static void __pcap_dns_data_info(const u_char *packet)
                char ip[BUFF_SIZE_IP];
 
                if (i == 0) {
-                       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                       if (STC_PCAP_LOG)
                                STC_LOGD("[Answers]");
                }
 
@@ -533,7 +532,7 @@ static void __pcap_dns_data_info(const u_char *packet)
                        case DNS_QTYPE_A:
                                inet_ntop(AF_INET, (struct in_addr *)&data[10],
                                        ip, BUFF_SIZE_IP);
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s] "
                                                "TTL[%u] Data length[%u] Address[%s]",
                                                name, type, __pcap_dns_type_info(type),
@@ -544,7 +543,7 @@ static void __pcap_dns_data_info(const u_char *packet)
                                __pcap_dns_name_info((uint8_t *)dns_h, &data[10], cname);
                                if (data == NULL)
                                        return;
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s] "
                                                "TTL[%u] Data length[%u] CName[%s]",
                                                name, type, __pcap_dns_type_info(type),
@@ -554,7 +553,7 @@ static void __pcap_dns_data_info(const u_char *packet)
                        case DNS_QTYPE_AAAA:
                                break;
                        default:
-                               if (STC_DEBUG_LOG && STC_PCAP_LOG)
+                               if (STC_PCAP_LOG)
                                        STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s] "
                                                "TTL[%u] Data length[%u]",
                                                name, type, __pcap_dns_type_info(type),
@@ -568,19 +567,20 @@ static void __pcap_dns_data_info(const u_char *packet)
        }
 }
 
-static void __pcap_dns_info(const u_char *packet)
+static void __pcap_dns_info(const u_char **packet)
 {
-       dns_t *dns_h = (dns_t *)(packet +
-               SIZE_ETHER_HEADER + SIZE_IP_HEADER + SIZE_UDP_HEADER);
+       dns_t *dns_h = (dns_t *)*packet;
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Transaction ID[0x%x] Flags[0x%x] Questions[%u] "
                        "Answer RRs[%u] Authority RRs[%u] Additional RRs[%u]",
                        ntohs(dns_h->id), ntohs(dns_h->flags),
                        ntohs(dns_h->questions), ntohs(dns_h->answerRR),
                        ntohs(dns_h->authorityRR), ntohs(dns_h->additionalRR));
 
-       __pcap_dns_data_info(packet);
+       *packet += SIZE_DNS_HEADER;
+
+       __pcap_dns_data_info(packet, dns_h);
 }
 
 static const char *__pcap_icmp_code_info(u_int8_t type, u_int8_t code)
@@ -728,59 +728,61 @@ static const char *__pcap_icmp_type_info(u_int8_t type)
        return info;
 }
 
-static void __pcap_icmp_info(const u_char *packet)
+static void __pcap_icmp_info(const u_char **packet)
 {
-       icmp_t *icmp_h = (icmp_t *)(packet +
-               SIZE_ETHER_HEADER + SIZE_IP_HEADER);
+       icmp_t *icmp_h = (icmp_t *)*packet;
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Type[%u:%s] Code[%u:%s] Checksum[0x%x]",
                        icmp_h->type, __pcap_icmp_type_info(icmp_h->type),
                        icmp_h->code, __pcap_icmp_code_info(icmp_h->type, icmp_h->code),
                        ntohs(icmp_h->checksum));
 }
 
-static void __pcap_tcp_info(const u_char *packet)
+static void __pcap_tcp_info(const u_char **packet)
 {
-       tcp_t *tcp_h = (tcp_t *)(packet +
-               SIZE_ETHER_HEADER + SIZE_IP_HEADER);
+       tcp_t *tcp_h = (tcp_t *)*packet;
        u_int16_t source = ntohs(tcp_h->source);
        u_int16_t dest = ntohs(tcp_h->dest);
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Source[%u] Destination[%u] Sequence[%u] "
                        "Acknowledgment seq[%u] Window size[%u] ",
                        ntohs(tcp_h->source), ntohs(tcp_h->dest),
                        ntohl(tcp_h->seq), ntohl(tcp_h->ack_seq),
                        ntohs(tcp_h->window));
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Checksum[0x%x] URG[%u] ACK[%u] PUSH[%u] "
                "RST[%u] SYN[%u] FIN[%u]",
                ntohs(tcp_h->check),
                tcp_h->urg, tcp_h->ack, tcp_h->psh,
                tcp_h->rst, tcp_h->syn, tcp_h->fin);
 
+       *packet += SIZE_TCP_HEADER;
+
        if (IS_SRC_OR_DST_PORT(PORT_DNS))
                __pcap_dns_info(packet);
 }
 
-static void __pcap_udp_info(const u_char *packet)
+static void __pcap_udp_info(const u_char **packet)
 {
-       udp_t *udp_h = (udp_t *)(packet
-               + SIZE_ETHER_HEADER + SIZE_IP_HEADER);
+       udp_t *udp_h = (udp_t *)*packet;
        u_int16_t source = ntohs(udp_h->source);
        u_int16_t dest = ntohs(udp_h->dest);
+       u_int16_t len = ntohs(udp_h->len);
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Source[%u] Destination[%u] Len[%u] Checksum[0x%x]",
-                       source, dest, ntohs(udp_h->len), ntohs(udp_h->check));
+                       source, dest, len, ntohs(udp_h->check));
+
+       *packet += SIZE_UDP_HEADER;
 
        if (IS_SRC_OR_DST_PORT(PORT_DNS))
                __pcap_dns_info(packet);
        else if (IS_SRC_OR_DST_PORT(PORT_BOOTP_C) ||
                IS_SRC_OR_DST_PORT(PORT_BOOTP_S))
-               __pcap_bootp_info(packet);
+               __pcap_bootp_info(packet, len);
        else if (IS_SRC_OR_DST_PORT(PORT_NTP))
                __pcap_ntp_info(packet);
 }
@@ -838,11 +840,10 @@ static const char *__pcap_arp_opcode_info(u_int16_t opcode)
        return info;
 }
 
-static void __pcap_arp_info(const u_char *packet)
+static void __pcap_arp_info(const u_char **packet)
 {
-       arp_t *arp_h = (arp_t *)(packet + SIZE_ETHER_HEADER);
-       u_int8_t *sha = (u_int8_t *)(packet +
-               SIZE_ETHER_HEADER + SIZE_ARP_HEADER);
+       arp_t *arp_h = (arp_t *)*packet;
+       u_int8_t *sha = (u_int8_t *)(*packet + SIZE_ARP_HEADER);
        u_int8_t *spa = (u_int8_t *)(sha + arp_h->ar_hln);
        u_int8_t *tha = (u_int8_t *)(spa + arp_h->ar_pln);
        u_int8_t *tpa = (u_int8_t *)(tha + arp_h->ar_hln);
@@ -865,7 +866,7 @@ static void __pcap_arp_info(const u_char *packet)
 
        ar_pro = ntohs(arp_h->ar_pro);
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("HW type[%u] Protocol type[0x%04x:%s] "
                        "HW size[%u] Protocol size[%u] Opcode[%u:%s] ",
                        ntohs(arp_h->ar_hrd), ar_pro,
@@ -873,7 +874,7 @@ static void __pcap_arp_info(const u_char *packet)
                        arp_h->ar_hln, arp_h->ar_pln,
                        ar_op, __pcap_arp_opcode_info(ar_op));
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Sender MAC[%s] Sender IP[%s] "
                        "Target MAC[%s] Target IP[%s]",
                        sma, sia, tma, tia);
@@ -913,16 +914,16 @@ static const char *__pcap_ip_protocol_info(u_int8_t p)
        return info;
 }
 
-static void __pcap_ipv6_info(const u_char *packet)
+static void __pcap_ipv6_info(const u_char **packet)
 {
-       ip6_t *ip6_h = (ip6_t *)(packet + SIZE_ETHER_HEADER);
+       ip6_t *ip6_h = (ip6_t *)*packet;
        char ip6_src[BUFF_SIZE_IP6];
        char ip6_dst[BUFF_SIZE_IP6];
 
        inet_ntop(AF_INET6, &ip6_h->ip6_src, ip6_src, BUFF_SIZE_IP6);
        inet_ntop(AF_INET6, &ip6_h->ip6_dst, ip6_dst, BUFF_SIZE_IP6);
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Flow[0x%08x] Payload len[%u] Next hdr[%u:%s] "
                        "Hop limit[%u] Source[%s] Destination[%s]",
                        ntohl(ip6_h->ip6_flow), ntohs(ip6_h->ip6_plen),
@@ -949,16 +950,16 @@ static void __pcap_ipv6_info(const u_char *packet)
        }
 }
 
-static void __pcap_ip_info(const u_char *packet)
+static void __pcap_ip_info(const u_char **packet)
 {
-       ip_t *ip_h = (ip_t *)(packet + SIZE_ETHER_HEADER);
+       ip_t *ip_h = (ip_t *)*packet;
        char ip_src[BUFF_SIZE_IP];
        char ip_dst[BUFF_SIZE_IP];
 
        inet_ntop(AF_INET, &ip_h->ip_src, ip_src, BUFF_SIZE_IP);
        inet_ntop(AF_INET, &ip_h->ip_dst, ip_dst, BUFF_SIZE_IP);
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Header len[%u] TOS[0x%02x] Total len[%u] "
                        "ID[0x%04x] Flags[0x%02x] TTL[%u] Protocol[%u:%s] "
                        "Checksum[0x%04x] Source[%s] Destination[%s]",
@@ -969,6 +970,8 @@ static void __pcap_ip_info(const u_char *packet)
                        __pcap_ip_protocol_info(ip_h->ip_p),
                        ntohs(ip_h->ip_sum), ip_src, ip_dst);
 
+       *packet += SIZE_IP_HEADER;
+
        switch (ip_h->ip_p) {
        case IPPROTO_ICMP:
                __pcap_icmp_info(packet);
@@ -984,9 +987,9 @@ static void __pcap_ip_info(const u_char *packet)
        }
 }
 
-static void __pcap_eth_info(const u_char *packet)
+static void __pcap_eth_info(const u_char **packet)
 {
-       eth_t *eth_h = (eth_t *)packet;
+       eth_t *eth_h = (eth_t *)*packet;
        u_int8_t *eth_shost = eth_h->ether_shost;
        u_int8_t *eth_dhost = eth_h->ether_dhost;
        char shost[BUFF_SIZE_HOST];
@@ -1003,9 +1006,219 @@ static void __pcap_eth_info(const u_char *packet)
 
        ether_type = ntohs(eth_h->ether_type);
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Source[%s] Destination[%s] Type[0x%04x:%s]",
                        shost, dhost, ether_type, __pcap_eth_type_info(ether_type));
+
+       *packet += SIZE_ETHER_HEADER;
+}
+
+static const char *__pcap_family_info(u_int8_t family)
+{
+       char *info = NULL;
+
+       switch (family) {
+       case AF_INET:
+               info = "IPv4";
+               break;
+       case AF_INET6:
+               info = "IPv6";
+               break;
+       default:
+               info = "Unknown";
+               break;
+       }
+
+       return info;
+}
+
+static const char *__pcap_tlv_type_info(u_int16_t type)
+{
+       char *info = NULL;
+
+       switch (type) {
+       case NFULA_PACKET_HDR:
+               info = "NFULA_PACKET_HDR";
+               break;
+       case NFULA_MARK:
+               info = "NFULA_MARK";
+               break;
+       case NFULA_TIMESTAMP:
+               info = "NFULA_TIMESTAMP";
+               break;
+       case NFULA_IFINDEX_INDEV:
+               info = "NFULA_IFINDEX_INDEV";
+               break;
+       case NFULA_IFINDEX_OUTDEV:
+               info = "NFULA_IFINDEX_OUTDEV";
+               break;
+       case NFULA_IFINDEX_PHYSINDEV:
+               info = "NFULA_IFINDEX_PHYSINDEV";
+               break;
+       case NFULA_IFINDEX_PHYSOUTDEV:
+               info = "NFULA_IFINDEX_PHYSOUTDEV";
+               break;
+       case NFULA_HWADDR:
+               info = "NFULA_HWADDR";
+               break;
+       case NFULA_PAYLOAD:
+               info = "NFULA_PAYLOAD";
+               break;
+       case NFULA_PREFIX:
+               info = "NFULA_PREFIX";
+               break;
+       case NFULA_UID:
+               info = "NFULA_UID";
+               break;
+       case NFULA_SEQ:
+               info = "NFULA_SEQ";
+               break;
+       case NFULA_SEQ_GLOBAL:
+               info = "NFULA_SEQ_GLOBAL";
+               break;
+       case NFULA_GID:
+               info = "NFULA_GID";
+               break;
+       case NFULA_HWTYPE:
+               info = "NFULA_HWTYPE";
+               break;
+       case NFULA_HWHEADER:
+               info = "NFULA_HWHEADER";
+               break;
+       case NFULA_HWLEN:
+               info = "NFULA_HWLEN";
+               break;
+       default:
+               info = "Unknown";
+               break;
+       }
+
+       return info;
+}
+
+static void __pcap_nflog_tlv_info(const u_char **packet,
+                               u_int32_t length, u_int32_t caplen)
+{
+       nflog_tlv_t *tlv_h;
+       u_int16_t tlv_length;
+       u_int16_t tlv_type;
+       GString *value;
+       u_int16_t value_len;
+       u_char *value_pos = NULL;
+       gchar *value_str = NULL;
+
+       length -= SIZE_NFLOG_HDR;
+       caplen -= SIZE_NFLOG_HDR;
+
+       while (length > 0) {
+               if (caplen < SIZE_NFLOG_TLV || length < SIZE_NFLOG_TLV)
+                       break;
+
+               tlv_h = (nflog_tlv_t *)*packet;
+               tlv_length = tlv_h->tlv_length;
+               if (tlv_length % 4 != 0)
+                       tlv_length += 4 - tlv_length % 4;
+               tlv_type = tlv_h->tlv_type;
+
+               if (tlv_length < SIZE_NFLOG_TLV)
+                       break;
+
+               if (caplen < tlv_length || length < tlv_length)
+                       break;
+
+               if (STC_PCAP_LOG) {
+                       if (tlv_type != NFULA_PAYLOAD) {
+                               nflog_hwaddr_t *hwaddr;
+                               nflog_timestamp_s *timestamp;
+                               char host[BUFF_SIZE_HOST];
+                               u_int32_t sec;
+                               int len = 0;
+                               char *time = NULL;
+
+                               switch (tlv_type) {
+                               case NFULA_HWADDR:
+                                       hwaddr = (nflog_hwaddr_t *)((u_char *)tlv_h + SIZE_NFLOG_TLV);
+                                       g_strlcpy(host,
+                                               ether_ntoa((const struct ether_addr *)hwaddr->hw_addr),
+                                               sizeof(host));
+                                       STC_LOGD("Type[%s:%u] Length[%u] Hwaddr[%s]",
+                                               __pcap_tlv_type_info(tlv_type), tlv_type,
+                                               tlv_h->tlv_length, host);
+                                       break;
+                               case NFULA_TIMESTAMP:
+                                       timestamp = (nflog_timestamp_s *)((u_char *)tlv_h + SIZE_NFLOG_TLV);
+                                       sec = ntohl(timestamp->ts[1]);
+                                       time = ctime((const time_t *)&sec);
+                                       len = strlen(time);
+                                       time[len - 1] = '\0';
+
+                                       STC_LOGD("Type[%s:%u] Length[%u] Timestamp[%s]",
+                                               __pcap_tlv_type_info(tlv_type), tlv_type,
+                                               tlv_h->tlv_length, time);
+                                       break;
+                               case NFULA_PREFIX:
+                                       value_len = tlv_h->tlv_length - SIZE_NFLOG_TLV;
+                                       value = g_string_sized_new(value_len);
+                                       if (value) {
+                                               value_pos = (u_char *)tlv_h + SIZE_NFLOG_TLV;
+                                               while (value_len--)
+                                                       g_string_append_printf(value, "%c", *(value_pos++));
+                                               value_str = g_string_free(value, FALSE);
+                                       }
+
+                                       STC_LOGD("Type[%s:%u] Length[%u] Prefix[%s]",
+                                               __pcap_tlv_type_info(tlv_type), tlv_type,
+                                               tlv_h->tlv_length, value_str);
+
+                                       FREE(value_str);
+                                       break;
+                               default:
+                                       value_len = tlv_h->tlv_length - SIZE_NFLOG_TLV;
+                                       value = g_string_sized_new(value_len);
+                                       if (value) {
+                                               value_pos = (u_char *)tlv_h + SIZE_NFLOG_TLV;
+                                               while (value_len--)
+                                                       g_string_append_printf(value, "%02x", *(value_pos++));
+                                               value_str = g_string_free(value, FALSE);
+                                       }
+
+                                       STC_LOGD("Type[%s:%u] Length[%u] Value[%s]",
+                                               __pcap_tlv_type_info(tlv_type), tlv_type,
+                                               tlv_h->tlv_length, value_str);
+
+                                       FREE(value_str);
+                                       break;
+                               }
+                       } else {
+                               STC_LOGD("Type[%s:%u] Length[%u]",
+                                       __pcap_tlv_type_info(tlv_type),
+                                       tlv_type, tlv_h->tlv_length);
+                       }
+               }
+
+               if (tlv_type == NFULA_PAYLOAD) {
+                       *packet += SIZE_NFLOG_TLV;
+                       break;
+               }
+
+               *packet += tlv_length;
+               length -= tlv_length;
+               caplen -= tlv_length;
+       }
+}
+
+static void __pcap_nflog_hdr_info(const u_char **packet)
+{
+       nflog_hdr_t *hdr_h = (nflog_hdr_t *)*packet;
+       u_int8_t family = hdr_h->nflog_family;
+       u_int8_t version = hdr_h->nflog_version;
+       u_int16_t resource_id = ntohs(hdr_h->nflog_rid);
+
+       if (STC_PCAP_LOG)
+               STC_LOGD("Family[%s:%u] Version[%u] Resource id[%u]",
+                       __pcap_family_info(family), family, version, resource_id);
+
+       *packet += SIZE_NFLOG_HDR;
 }
 
 static void __pcap_fm_info(const struct pcap_pkthdr *pkthdr)
@@ -1014,7 +1227,7 @@ static void __pcap_fm_info(const struct pcap_pkthdr *pkthdr)
        int len = 0;
        struct timeval ts = pkthdr->ts;
        __time_t tv_sec = ts.tv_sec;
-       __suseconds_t tv_usec = tv_usec;
+       __suseconds_t tv_usec = ts.tv_usec;
 
        if (g_pcap_start_fm == false) {
                g_pcap_tv = ts;
@@ -1025,7 +1238,7 @@ static void __pcap_fm_info(const struct pcap_pkthdr *pkthdr)
        len = strlen(curr);
        curr[len - 1] = '\0';
 
-       if (STC_DEBUG_LOG && STC_PCAP_LOG)
+       if (STC_PCAP_LOG)
                STC_LOGD("Arrival time[%s] Timeval[%.06f] "
                        "Frame len[%u] Capture len[%u]", curr,
                        (float)((tv_sec - g_pcap_tv.tv_sec) * 1000000 +
@@ -1036,29 +1249,57 @@ static void __pcap_fm_info(const struct pcap_pkthdr *pkthdr)
 static void __pcap_handler(u_char *param,
                        const struct pcap_pkthdr *pkthdr,
                        const u_char *packet) {
-       eth_t *eth_h;
-       unsigned short eth_type;
        /* int len = pkthdr->len; */
+       stc_pcap_data_s *pcap_data = (stc_pcap_data_s *)param;
+       eth_t *eth_h;
+       u_int16_t eth_type;
+       nflog_hdr_t *nflog_h;
+       u_int8_t nflog_family;
 
        __pcap_fm_info(pkthdr);
 
-       eth_h = (eth_t *)packet;
-       __pcap_eth_info(packet);
+       switch (pcap_data->encap_type) {
+       case ENCAPTYPE_ETHERNET:
+               eth_h = (eth_t *)packet;
+               eth_type = ntohs(eth_h->ether_type);
 
-       eth_type = ntohs(eth_h->ether_type);
-       switch (eth_type) {
-       case ETHERTYPE_IP:
-               __pcap_ip_info(packet);
-               /* __pcap_data_info(pcaket, len); */
-               break;
-       case ETHERTYPE_IPV6:
-               __pcap_ipv6_info(packet);
-               break;
-       case ETHERTYPE_ARP:
-       case ETHERTYPE_REVARP:
-               __pcap_arp_info(packet);
+               __pcap_eth_info(&packet);
+
+               switch (eth_type) {
+               case ETHERTYPE_IP:
+                       __pcap_ip_info(&packet);
+                       /* __pcap_data_info(pcaket, len); */
+                       break;
+               case ETHERTYPE_IPV6:
+                       __pcap_ipv6_info(&packet);
+                       break;
+               case ETHERTYPE_ARP:
+               case ETHERTYPE_REVARP:
+                       __pcap_arp_info(&packet);
+                       break;
+               case ETHERTYPE_LOOPBACK:
+                       break;
+               default:
+                       break;
+               }
                break;
-       case ETHERTYPE_LOOPBACK:
+       case ENCAPTYPE_NFLOG:
+               nflog_h = (nflog_hdr_t *)packet;
+               nflog_family = nflog_h->nflog_family;
+
+               __pcap_nflog_hdr_info(&packet);
+               __pcap_nflog_tlv_info(&packet, pkthdr->len, pkthdr->caplen);
+
+               switch (nflog_family) {
+               case AF_INET:
+                       __pcap_ip_info(&packet);
+                       break;
+               case AF_INET6:
+                       __pcap_ipv6_info(&packet);
+                       break;
+               default:
+                       break;
+               }
                break;
        default:
                break;
@@ -1078,7 +1319,7 @@ static gboolean __pcap_thread_source_func(gpointer data)
        if (g_pcap_tables == NULL)
                return false;
 
-       snprintf(buf, sizeof(buf), "%s_%d",
+       snprintf(buf, sizeof(buf), "%s:%d",
                pcap_data->ifname, pcap_data->nflog_group);
 
        lookup = g_hash_table_lookup(g_pcap_tables, buf);
@@ -1113,7 +1354,13 @@ static gpointer __pcap_thread_func(gpointer data)
 
        for (dev = alldevs; dev; dev = dev->next) {
                if (g_strcmp0(dev->name, pcap_data->ifname) == 0) {
-                       name = g_strdup(dev->name);
+                       if (g_strcmp0(dev->name, NFLOG_IFNAME) == 0) {
+                               name = g_strdup(pcap_data->nfname);
+                               pcap_data->encap_type = ENCAPTYPE_NFLOG;
+                       } else {
+                               name = g_strdup(pcap_data->ifname);
+                               pcap_data->encap_type = ENCAPTYPE_ETHERNET;
+                       }
                        break;
                }
        }
@@ -1133,12 +1380,14 @@ static gpointer __pcap_thread_func(gpointer data)
                goto thread_exit;
        }
 
+       STC_LOGD("Pcap open live [%p]", pcap_data->handle);
+
        STC_LOGD("Pcap loop start [%s]", name);
-       pcap_loop(pcap_data->handle, 0, __pcap_handler, NULL);
+       pcap_loop(pcap_data->handle, 0, __pcap_handler, (u_char *)pcap_data);
        STC_LOGD("Pcap loop end [%s]", name);
 
        pcap_close(pcap_data->handle);
-       STC_LOGD("Pcap closed [%s]", name);
+       STC_LOGD("Pcap closed [%p]", pcap_data->handle);
 
 thread_exit:
        FREE(name);
@@ -1318,7 +1567,7 @@ int stc_plugin_pcap_register_loop(const char *ifname,
                STC_ERROR_FAIL,
                "Invalid parameter [ifname]");
 
-       snprintf(buf, sizeof(buf), "%s_%d", ifname, nflog_group);
+       snprintf(buf, sizeof(buf), "%s:%d", ifname, nflog_group);
 
        lookup = g_hash_table_lookup(g_pcap_tables, buf);
        if (lookup) {
@@ -1333,6 +1582,7 @@ int stc_plugin_pcap_register_loop(const char *ifname,
        }
 
        data->ifname = g_strdup(ifname);
+       data->nfname = g_strdup(buf);
        data->nflog_group = nflog_group;
        data->thread = g_thread_new(buf, __pcap_thread_func, data);
 
@@ -1356,7 +1606,7 @@ int stc_plugin_pcap_unregister_loop(const char *ifname,
                STC_ERROR_FAIL,
                "Invalid parameter [ifname]");
 
-       snprintf(buf, sizeof(buf), "%s_%d", ifname, nflog_group);
+       snprintf(buf, sizeof(buf), "%s:%d", ifname, nflog_group);
 
        lookup = g_hash_table_lookup(g_pcap_tables, buf);
        if (!lookup) {