2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "stc-plugin-pcap.h"
20 static GHashTable *g_pcap_tables = NULL;
21 static bool g_pcap_start_fm = false;
22 static struct timeval g_pcap_tv = { 0, };
24 static void __pcap_data_free(gpointer value)
26 stc_pcap_data_s *data = (stc_pcap_data_s *)value;
28 g_thread_unref(data->thread);
35 static void __pcap_data_info(const u_char *packet, int len)
39 data = g_string_sized_new(len);
44 g_string_append_printf(data, "%02x", *(packet++));
46 STC_LOGD("[%s]", g_string_free(data, FALSE));
50 static void __pcap_ntp_time_info(uint32_t s, char *time)
55 uint32_t sec = ntohl(s);
58 seconds = sec - NTP_JAN_1970;
59 curr = ctime(&seconds);
63 snprintf(time, len, "%s", curr);
65 snprintf(time, 10, "00:00:00");
69 static void __pcap_ntp_refid_info(ntp_t *ntp_h, char *refid)
71 switch (ntp_h->stratum) {
72 case NTP_STRATUM_UNSPECIFIED:
73 snprintf(refid, BUFF_SIZE_ID, "%s", "(unspec)");
75 case NTP_STRATUM_PRIM_REF:
76 snprintf(refid, BUFF_SIZE_ID, "%s", "(prim_ref)");
78 case NTP_STRATUM_INFO_QUERY:
79 snprintf(refid, BUFF_SIZE_ID, "%s INFO_QEURY",
80 inet_ntoa(*((struct in_addr *)&ntp_h->refid)));
82 case NTP_STRATUM_INFO_REPLY:
83 snprintf(refid, BUFF_SIZE_ID, "%s INFO_REPLY",
84 inet_ntoa(*((struct in_addr *)&ntp_h->refid)));
87 snprintf(refid, BUFF_SIZE_ID, "%s",
88 inet_ntoa(*((struct in_addr *)&ntp_h->refid)));
93 static uint16_t __pcap_ntp_fraction_info(uint16_t f)
98 ff = ntohs(f) / 65536.0;
99 fraction = (uint16_t)(ff * 1000000.0);
104 static void __pcap_ntp_info(const u_char *packet)
106 ntp_t *ntp_h = (ntp_t *)(packet +
107 SIZE_ETHER_HEADER + SIZE_IP_HEADER + SIZE_UDP_HEADER);
108 char refid[BUFF_SIZE_ID];
109 char reftime[BUFF_SIZE_TIME];
110 char orgtime[BUFF_SIZE_TIME];
111 char rectime[BUFF_SIZE_TIME];
112 char xmttime[BUFF_SIZE_TIME];
114 __pcap_ntp_refid_info(ntp_h, refid);
115 __pcap_ntp_time_info(ntp_h->reftime.second, reftime);
116 __pcap_ntp_time_info(ntp_h->orgtime.second, orgtime);
117 __pcap_ntp_time_info(ntp_h->rectime.second, rectime);
118 __pcap_ntp_time_info(ntp_h->xmttime.second, xmttime);
120 STC_LOGD("Flags[0x%02x] Stratum[%u] Poll[%u:%us] Precision[%u] "
121 "Root delay[%u.%06us] Root dispersion[%u.%06us] Ref ID[%s]",
122 ntp_h->flags, ntp_h->stratum, ntp_h->poll,
123 ntp_h->precision, 1 << ntp_h->precision,
124 ntohs(ntp_h->rootdelay.second),
125 __pcap_ntp_fraction_info(ntp_h->rootdelay.fraction),
126 ntohs(ntp_h->rootdisp.second),
127 __pcap_ntp_fraction_info(ntp_h->rootdisp.fraction),
130 STC_LOGD("Reference[%s] Origin[%s] Receive[%s] Transmit[%s]",
131 reftime, orgtime, rectime, xmttime);
134 static const char *__pcap_dhcp_client_id_info(uint8_t data)
139 case DHCP_CLIENT_ID_ETHERNET:
142 case DHCP_CLIENT_ID_IEEE802:
143 info = "IEEE 802 Networks";
145 case DHCP_CLIENT_ID_ARCNET:
148 case DHCP_CLIENT_ID_LOCALTALK:
151 case DHCP_CLIENT_ID_LOCALNET:
154 case DHCP_CLIENT_ID_SMDS:
157 case DHCP_CLIENT_ID_FRAMERELAY:
158 info = "Frame Relay";
160 case DHCP_CLIENT_ID_ATM1:
161 info = "ATM(Async Transfer Mode)";
163 case DHCP_CLIENT_ID_HDLC:
166 case DHCP_CLIENT_ID_FIBRECHANNEL:
167 info = "Fibre Channel";
169 case DHCP_CLIENT_ID_ATM2:
170 info = "ATM(Async Transfer Mode)";
172 case DHCP_CLIENT_ID_SERIALLINE:
173 info = "Serial Line";
183 static const char *__pcap_dhcp_msg_type_info(uint8_t type)
188 case DHCP_MSG_TYPE_DISCOVER:
191 case DHCP_MSG_TYPE_OFFER:
194 case DHCP_MSG_TYPE_REQUEST:
197 case DHCP_MSG_TYPE_DECLINE:
200 case DHCP_MSG_TYPE_ACK:
203 case DHCP_MSG_TYPE_NAK:
206 case DHCP_MSG_TYPE_RELEASE:
209 case DHCP_MSG_TYPE_INFORM:
220 static void __pcap_bootp_magic_info(uint32_t magic,
221 uint8_t *moption, u_int16_t len)
223 if (ntohl(magic) == BOOTP_MAGIC_DHCP) {
224 char buf[BOOTP_MOPTION_LEN];
225 uint8_t *opt = moption;
227 STC_LOGD("Magic cookie[DHCP]");
230 uint8_t tag = opt[0];
231 uint8_t length = opt[1];
232 uint8_t *data = &opt[2];
233 char addr[BUFF_SIZE_IP];
234 char host[BUFF_SIZE_HOST];
237 case DHCP_TAG_SUBNET_MASK:
238 inet_ntop(AF_INET, (struct in_addr *)data,
240 STC_LOGD("Subnet mask[%s]", addr);
242 case DHCP_TAG_ROUTER:
243 inet_ntop(AF_INET, (struct in_addr *)data,
245 STC_LOGD("Router[%s]", addr);
248 inet_ntop(AF_INET, (struct in_addr *)data,
250 STC_LOGD("Domain name server[%s]", addr);
252 case DHCP_TAG_HOST_NAME:
253 snprintf(buf, ((length < BOOTP_MOPTION_LEN) ?
254 (length + 1) : BOOTP_MOPTION_LEN), "%s", (char *)data);
255 STC_LOGD("Host name[%s]", buf);
257 case DHCP_TAG_REQUESTED_IP:
258 inet_ntop(AF_INET, (struct in_addr *)data,
260 STC_LOGD("Requested IP[%s]", addr);
262 case DHCP_TAG_IP_LEASE_TIME:
263 STC_LOGD("IP address lease time[%us]",
264 ntohl(*(uint32_t *)data));
266 case DHCP_TAG_MSG_TYPE:
267 STC_LOGD("DHCP message type[%u:%s]", *data,
268 __pcap_dhcp_msg_type_info(*data));
270 case DHCP_TAG_SERVER_ID:
271 inet_ntop(AF_INET, (struct in_addr *)data,
273 STC_LOGD("DHCP server identifier[%s]", addr);
275 case DHCP_TAG_MSG_SIZE:
276 STC_LOGD("Maximum DHCP message size[%u]",
277 ntohs(*(uint16_t *)data));
279 case DHCP_TAG_CLIENT_ID:
280 STC_LOGD("Client identifier HW type[0x%02x:%s]", *data,
281 __pcap_dhcp_client_id_info(*data));
282 if (*data == DHCP_CLIENT_ID_ETHERNET) {
284 ether_ntoa((const struct ether_addr *)&data[1]),
286 STC_LOGD("Client identifier MAC[%s]", host);
293 STC_LOGD("Unknown[%u]", tag);
303 static const char *__pcap_bootp_op_info(uint8_t op)
322 static void __pcap_bootp_info(const u_char *packet)
324 udp_t *udp_h = (udp_t *)(packet
325 + SIZE_ETHER_HEADER + SIZE_IP_HEADER);
326 bootp_t *bootp_h = (bootp_t *)(packet +
327 SIZE_ETHER_HEADER + SIZE_IP_HEADER + SIZE_UDP_HEADER);
328 char ciaddr[BUFF_SIZE_IP];
329 char yiaddr[BUFF_SIZE_IP];
330 char siaddr[BUFF_SIZE_IP];
331 char giaddr[BUFF_SIZE_IP];
332 char chaddr[BUFF_SIZE_HOST];
335 inet_ntop(AF_INET, &bootp_h->ciaddr, ciaddr, BUFF_SIZE_IP);
336 inet_ntop(AF_INET, &bootp_h->yiaddr, yiaddr, BUFF_SIZE_IP);
337 inet_ntop(AF_INET, &bootp_h->siaddr, siaddr, BUFF_SIZE_IP);
338 inet_ntop(AF_INET, &bootp_h->giaddr, giaddr, BUFF_SIZE_IP);
341 ether_ntoa((const struct ether_addr *)bootp_h->chaddr),
344 STC_LOGD("Message type[%u:%s] HW type[0x%02x] HW len[%u] Hops[%u] "
345 "Transaction ID[0x%08x] Seconds elapsed[%u] Flags[0x%04x]",
346 bootp_h->op, __pcap_bootp_op_info(bootp_h->op),
347 bootp_h->htype, bootp_h->hlen, bootp_h->hops,
348 ntohl(bootp_h->xid), ntohs(bootp_h->secs), ntohs(bootp_h->flags));
350 STC_LOGD("Client[%s] Your(client)[%s] Next server[%s] "
351 "Relay agent[%s] Client MAC[%s]",
352 ciaddr, yiaddr, siaddr, giaddr, chaddr);
354 len = ntohs(udp_h->len);
355 __pcap_bootp_magic_info(bootp_h->magic, bootp_h->moption, len);
358 static char *__pcap_dns_type_info(uint16_t type)
366 case DNS_QTYPE_CNAME:
380 static char *__pcap_dns_class_info(uint16_t class)
388 case DNS_QCLASS_CHAOS:
405 static uint8_t * __pcap_dns_name_info(uint8_t *dns_h,
406 uint8_t *data, u_char *name)
409 u_char *dname = name;
416 sec = (uint8_t *)dns_h +
417 (htons(*(uint16_t *)sec) & 0x3FFF);
425 if (dname - name + *sec + 1 > BUFF_SIZE_NAME - 1) {
430 memcpy(dname, sec + 1, *sec);
443 return (uint8_t *)nxt;
446 static void __pcap_dns_data_info(const u_char *packet)
448 dns_t *dns_h = (dns_t *)(packet +
449 SIZE_ETHER_HEADER + SIZE_IP_HEADER +
451 uint8_t *data = (uint8_t *)(packet +
452 SIZE_ETHER_HEADER + SIZE_IP_HEADER +
453 SIZE_UDP_HEADER + SIZE_DNS_HEADER);
454 uint16_t qdcount = ntohs(dns_h->questions);
455 uint16_t ancount = ntohs(dns_h->answerRR);
458 for (i = 0; i < qdcount; ++i) {
459 u_char name[BUFF_SIZE_NAME];
464 STC_LOGD("[Queries]");
466 data = __pcap_dns_name_info((uint8_t *)dns_h, data, name);
470 type = ntohs(*(uint16_t *)&data[0]);
471 class = ntohs(*(uint16_t *)&data[2]);
473 STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s]",
474 name, type, __pcap_dns_type_info(type),
475 class, __pcap_dns_class_info(class));
480 for (i = 0; i < ancount; ++i) {
481 u_char name[BUFF_SIZE_NAME];
482 u_char cname[BUFF_SIZE_NAME];
487 char ip[BUFF_SIZE_IP];
490 STC_LOGD("[Answers]");
492 data = __pcap_dns_name_info((uint8_t *)dns_h, data, name);
496 type = ntohs(*(uint16_t *)&data[0]);
497 class = ntohs(*(uint16_t *)&data[2]);
498 ttl = ntohl(*(uint32_t *)&data[4]);
499 length = ntohs(*(uint16_t *)&data[8]);
501 if (class == DNS_QCLASS_IN) {
504 inet_ntop(AF_INET, (struct in_addr *)&data[10],
506 STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s] "
507 "TTL[%u] Data length[%u] Address[%s]",
508 name, type, __pcap_dns_type_info(type),
509 class, __pcap_dns_class_info(class),
512 case DNS_QTYPE_CNAME:
513 __pcap_dns_name_info((uint8_t *)dns_h, &data[10], cname);
516 STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s] "
517 "TTL[%u] Data length[%u] CName[%s]",
518 name, type, __pcap_dns_type_info(type),
519 class, __pcap_dns_class_info(class),
525 STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s] "
526 "TTL[%u] Data length[%u]",
527 name, type, __pcap_dns_type_info(type),
528 class, __pcap_dns_class_info(class),
534 data += (length + 10);
538 static void __pcap_dns_info(const u_char *packet)
540 dns_t *dns_h = (dns_t *)(packet +
541 SIZE_ETHER_HEADER + SIZE_IP_HEADER + SIZE_UDP_HEADER);
543 STC_LOGD("Transaction ID[0x%x] Flags[0x%x] Questions[%u] "
544 "Answer RRs[%u] Authority RRs[%u] Additional RRs[%u]",
545 ntohs(dns_h->id), ntohs(dns_h->flags),
546 ntohs(dns_h->questions), ntohs(dns_h->answerRR),
547 ntohs(dns_h->authorityRR), ntohs(dns_h->additionalRR));
549 __pcap_dns_data_info(packet);
552 static const char *__pcap_icmp_code_info(u_int8_t type, u_int8_t code)
557 case ICMP_DEST_UNREACH:
559 case ICMP_NET_UNREACH:
560 info = "Network Unreachable";
562 case ICMP_HOST_UNREACH:
563 info = "Host Unreachable";
565 case ICMP_PROT_UNREACH:
566 info = "Protocol Unreachable";
568 case ICMP_PORT_UNREACH:
569 info = "Port Unreachable";
571 case ICMP_FRAG_NEEDED:
572 info = "Fragmentation Needed/DF set";
575 info = "Source Route failed";
577 case ICMP_NET_UNKNOWN:
579 case ICMP_HOST_UNKNOWN:
581 case ICMP_HOST_ISOLATED:
587 case ICMP_NET_UNR_TOS:
589 case ICMP_HOST_UNR_TOS:
591 case ICMP_PKT_FILTERED:
592 info = "Packet filtered";
594 case ICMP_PREC_VIOLATION:
595 info = "Precedence violation";
597 case ICMP_PREC_CUTOFF:
598 info = "Precedence cut off";
608 info = "Redirect Net";
610 case ICMP_REDIR_HOST:
611 info = "Redirect Host";
613 case ICMP_REDIR_NETTOS:
614 info = "Redirect Net for TOS";
616 case ICMP_REDIR_HOSTTOS:
617 info = "Redirect Host for TOS";
624 case ICMP_TIME_EXCEEDED:
627 info = "TTL count exceeded";
629 case ICMP_EXC_FRAGTIME:
630 info = "Fragment Reass time exceeded";
645 static const char *__pcap_icmp_type_info(u_int8_t type)
653 case ICMP_DEST_UNREACH:
654 info = "Destination Unreachable";
656 case ICMP_SOURCE_QUENCH:
657 info = "Source Quench";
663 info = "Echo Request";
665 case ICMP_TIME_EXCEEDED:
666 info = "Time Exceeded";
668 case ICMP_PARAMETERPROB:
669 info = "Parameter Problem";
672 info = "Timestamp Request";
674 case ICMP_TIMESTAMPREPLY:
675 info = "Timestamp Reply";
677 case ICMP_INFO_REQUEST:
678 info = "Information Request";
680 case ICMP_INFO_REPLY:
681 info = "Information Reply";
684 info = "Address Mask Request";
686 case ICMP_ADDRESSREPLY:
687 info = "Address Mask Reply";
697 static void __pcap_icmp_info(const u_char *packet)
699 icmp_t *icmp_h = (icmp_t *)(packet +
700 SIZE_ETHER_HEADER + SIZE_IP_HEADER);
702 STC_LOGD("Type[%u:%s] Code[%u:%s] Checksum[0x%x]",
703 icmp_h->type, __pcap_icmp_type_info(icmp_h->type),
704 icmp_h->code, __pcap_icmp_code_info(icmp_h->type, icmp_h->code),
705 ntohs(icmp_h->checksum));
708 static void __pcap_tcp_info(const u_char *packet)
710 tcp_t *tcp_h = (tcp_t *)(packet +
711 SIZE_ETHER_HEADER + SIZE_IP_HEADER);
712 u_int16_t source = ntohs(tcp_h->source);
713 u_int16_t dest = ntohs(tcp_h->dest);
715 STC_LOGD("Source[%u] Destination[%u] Sequence[%u] "
716 "Acknowledgment seq[%u] Window size[%u] ",
717 ntohs(tcp_h->source), ntohs(tcp_h->dest),
718 ntohl(tcp_h->seq), ntohl(tcp_h->ack_seq),
719 ntohs(tcp_h->window));
721 STC_LOGD("Checksum[0x%x] URG[%u] ACK[%u] PUSH[%u] "
722 "RST[%u] SYN[%u] FIN[%u]",
724 tcp_h->urg, tcp_h->ack, tcp_h->psh,
725 tcp_h->rst, tcp_h->syn, tcp_h->fin);
727 if (IS_SRC_OR_DST_PORT(PORT_DNS))
728 __pcap_dns_info(packet);
731 static void __pcap_udp_info(const u_char *packet)
733 udp_t *udp_h = (udp_t *)(packet
734 + SIZE_ETHER_HEADER + SIZE_IP_HEADER);
735 u_int16_t source = ntohs(udp_h->source);
736 u_int16_t dest = ntohs(udp_h->dest);
738 STC_LOGD("Source[%u] Destination[%u] Len[%u] Checksum[0x%x]",
739 source, dest, ntohs(udp_h->len), ntohs(udp_h->check));
741 if (IS_SRC_OR_DST_PORT(PORT_DNS))
742 __pcap_dns_info(packet);
743 else if (IS_SRC_OR_DST_PORT(PORT_BOOTP_C) ||
744 IS_SRC_OR_DST_PORT(PORT_BOOTP_S))
745 __pcap_bootp_info(packet);
746 else if (IS_SRC_OR_DST_PORT(PORT_NTP))
747 __pcap_ntp_info(packet);
750 static const char *__pcap_eth_type_info(u_int16_t type)
764 case ETHERTYPE_REVARP:
767 case ETHERTYPE_LOOPBACK:
778 static const char *__pcap_arp_opcode_info(u_int16_t opcode)
803 static void __pcap_arp_info(const u_char *packet)
805 arp_t *arp_h = (arp_t *)(packet + SIZE_ETHER_HEADER);
806 u_int8_t *sha = (u_int8_t *)(packet +
807 SIZE_ETHER_HEADER + SIZE_ARP_HEADER);
808 u_int8_t *spa = (u_int8_t *)(sha + arp_h->ar_hln);
809 u_int8_t *tha = (u_int8_t *)(spa + arp_h->ar_pln);
810 u_int8_t *tpa = (u_int8_t *)(tha + arp_h->ar_hln);
811 u_int16_t ar_op = ntohs(arp_h->ar_op);
812 char sma[BUFF_SIZE_HOST];
813 char sia[BUFF_SIZE_IP];
814 char tma[BUFF_SIZE_HOST];
815 char tia[BUFF_SIZE_IP];
819 ether_ntoa((const struct ether_addr *)sha),
822 ether_ntoa((const struct ether_addr *)tha),
825 inet_ntop(AF_INET, (struct in_addr *)spa, sia, BUFF_SIZE_IP);
826 inet_ntop(AF_INET, (struct in_addr *)tpa, tia, BUFF_SIZE_IP);
828 ar_pro = ntohs(arp_h->ar_pro);
830 STC_LOGD("HW type[%u] Protocol type[0x%04x:%s] "
831 "HW size[%u] Protocol size[%u] Opcode[%u:%s] ",
832 ntohs(arp_h->ar_hrd), ar_pro,
833 __pcap_eth_type_info(ar_pro),
834 arp_h->ar_hln, arp_h->ar_pln,
835 ar_op, __pcap_arp_opcode_info(ar_op));
837 STC_LOGD("Sender MAC[%s] Sender IP[%s] "
838 "Target MAC[%s] Target IP[%s]",
842 static const char *__pcap_ip_protocol_info(u_int8_t p)
876 static void __pcap_ipv6_info(const u_char *packet)
878 ip6_t *ip6_h = (ip6_t *)(packet + SIZE_ETHER_HEADER);
879 char ip6_src[BUFF_SIZE_IP6];
880 char ip6_dst[BUFF_SIZE_IP6];
882 inet_ntop(AF_INET6, &ip6_h->ip6_src, ip6_src, BUFF_SIZE_IP6);
883 inet_ntop(AF_INET6, &ip6_h->ip6_dst, ip6_dst, BUFF_SIZE_IP6);
885 STC_LOGD("Flow[0x%08x] Payload len[%u] Next hdr[%u:%s] "
886 "Hop limit[%u] Source[%s] Destination[%s]",
887 ntohl(ip6_h->ip6_flow), ntohs(ip6_h->ip6_plen),
888 ip6_h->ip6_nxt, __pcap_ip_protocol_info(ip6_h->ip6_nxt),
889 ip6_h->ip6_hlim, ip6_src, ip6_dst);
891 switch (ip6_h->ip6_nxt) {
911 static void __pcap_ip_info(const u_char *packet)
913 ip_t *ip_h = (ip_t *)(packet + SIZE_ETHER_HEADER);
914 char ip_src[BUFF_SIZE_IP];
915 char ip_dst[BUFF_SIZE_IP];
917 inet_ntop(AF_INET, &ip_h->ip_src, ip_src, BUFF_SIZE_IP);
918 inet_ntop(AF_INET, &ip_h->ip_dst, ip_dst, BUFF_SIZE_IP);
920 STC_LOGD("Header len[%u] TOS[0x%02x] Total len[%u] "
921 "ID[0x%04x] Flags[0x%02x] TTL[%u] Protocol[%u:%s] "
922 "Checksum[0x%04x] Source[%s] Destination[%s]",
923 ip_h->ip_hl << 2, ip_h->ip_tos,
924 ntohs(ip_h->ip_len), ntohs(ip_h->ip_id),
925 (ntohs(ip_h->ip_off) & 0xe000) >> 13,
926 ip_h->ip_ttl, ip_h->ip_p,
927 __pcap_ip_protocol_info(ip_h->ip_p),
928 ntohs(ip_h->ip_sum), ip_src, ip_dst);
930 switch (ip_h->ip_p) {
932 __pcap_icmp_info(packet);
935 __pcap_tcp_info(packet);
938 __pcap_udp_info(packet);
945 static void __pcap_eth_info(const u_char *packet)
947 eth_t *eth_h = (eth_t *)packet;
948 u_int8_t *eth_shost = eth_h->ether_shost;
949 u_int8_t *eth_dhost = eth_h->ether_dhost;
950 char shost[BUFF_SIZE_HOST];
951 char dhost[BUFF_SIZE_HOST];
952 u_int16_t ether_type;
955 ether_ntoa((const struct ether_addr *)eth_shost),
959 ether_ntoa((const struct ether_addr *)eth_dhost),
962 ether_type = ntohs(eth_h->ether_type);
964 STC_LOGD("Source[%s] Destination[%s] Type[0x%04x:%s]",
965 shost, dhost, ether_type, __pcap_eth_type_info(ether_type));
968 static void __pcap_fm_info(const struct pcap_pkthdr *pkthdr)
972 struct timeval ts = pkthdr->ts;
973 __time_t tv_sec = ts.tv_sec;
974 __suseconds_t tv_usec = tv_usec;
976 if (g_pcap_start_fm == false) {
978 g_pcap_start_fm = true;
981 curr = ctime((const time_t *)&tv_sec);
983 curr[len - 1] = '\0';
985 STC_LOGD("Arrival time[%s] Timeval[%.06f] "
986 "Frame len[%u] Capture len[%u]", curr,
987 (float)((tv_sec - g_pcap_tv.tv_sec) * 1000000 +
988 (tv_usec - g_pcap_tv.tv_usec)) / 1000000,
989 pkthdr->len, pkthdr->caplen);
992 static void __pcap_handler(u_char *param,
993 const struct pcap_pkthdr *pkthdr,
994 const u_char *packet) {
996 unsigned short eth_type;
997 /* int len = pkthdr->len; */
999 __pcap_fm_info(pkthdr);
1001 eth_h = (eth_t *)packet;
1002 __pcap_eth_info(packet);
1004 eth_type = ntohs(eth_h->ether_type);
1007 __pcap_ip_info(packet);
1008 /* __pcap_data_info(pcaket, len); */
1010 case ETHERTYPE_IPV6:
1011 __pcap_ipv6_info(packet);
1014 case ETHERTYPE_REVARP:
1015 __pcap_arp_info(packet);
1017 case ETHERTYPE_LOOPBACK:
1024 static gboolean __pcap_thread_source_func(gpointer data)
1026 char buf[MAX_IFACE_LENGTH];
1027 stc_pcap_data_s *lookup;
1028 stc_pcap_data_s *pcap_data = (stc_pcap_data_s *)data;
1030 g_pcap_tv.tv_sec = 0;
1031 g_pcap_tv.tv_usec = 0;
1032 g_pcap_start_fm = false;
1034 if (g_pcap_tables == NULL)
1037 snprintf(buf, sizeof(buf), "%s_%d",
1038 pcap_data->name, pcap_data->group);
1040 lookup = g_hash_table_lookup(g_pcap_tables, buf);
1042 STC_LOGE("pcap loop not found");
1046 g_hash_table_remove(g_pcap_tables, buf);
1047 STC_LOGD("Successfully removed pcap loop [%s]", buf);
1052 static gpointer __pcap_thread_func(gpointer data)
1054 __STC_LOG_FUNC_ENTER__;
1056 char errbuf[PCAP_ERRBUF_SIZE];
1057 pcap_if_t *alldevs = NULL;
1058 pcap_if_t *dev = NULL;
1060 GSource *source = NULL;
1061 GMainContext *context = NULL;
1062 stc_pcap_data_s *pcap_data = (stc_pcap_data_s *)data;
1064 if (pcap_findalldevs(&alldevs, errbuf) < 0 ||
1066 STC_LOGE("Failed to find all devs [%s]", errbuf);
1070 for (dev = alldevs; dev; dev = dev->next) {
1071 if (g_strcmp0(dev->name, pcap_data->name) == 0) {
1072 name = g_strdup(dev->name);
1077 pcap_freealldevs(alldevs);
1080 STC_LOGE("Failed to find dev [%s]", pcap_data->name);
1084 STC_LOGD("Pcap source dev [%s]", name);
1086 pcap_data->handle = pcap_open_live(name, 65535, 1, 1000, errbuf);
1087 if (pcap_data->handle == NULL) {
1088 STC_LOGE("Failed to open live [%s]", errbuf);
1092 pcap_loop(pcap_data->handle, 0, __pcap_handler, NULL);
1094 pcap_close(pcap_data->handle);
1099 context = g_main_context_default();
1101 source = g_idle_source_new();
1103 g_source_set_callback(source,
1104 __pcap_thread_source_func, pcap_data, NULL);
1105 g_source_attach(source, context);
1107 g_source_unref(source);
1109 __STC_LOG_FUNC_EXIT__;
1113 int stc_plugin_pcap_initialize(void)
1115 __STC_LOG_FUNC_ENTER__;
1117 g_pcap_tables = g_hash_table_new_full(g_str_hash,
1118 g_str_equal, g_free, __pcap_data_free);
1120 __STC_LOG_FUNC_EXIT__;
1121 return STC_ERROR_NONE;
1124 int stc_plugin_pcap_deinitialize(void)
1126 __STC_LOG_FUNC_ENTER__;
1128 if (g_pcap_tables) {
1129 g_hash_table_destroy(g_pcap_tables);
1130 g_pcap_tables = NULL;
1133 __STC_LOG_FUNC_EXIT__;
1134 return STC_ERROR_NONE;
1137 int stc_plugin_pcap_lookup_dev(void)
1139 __STC_LOG_FUNC_ENTER__;
1142 char errbuf[PCAP_ERRBUF_SIZE];
1144 dev = pcap_lookupdev(errbuf);
1146 STC_LOGE("Failed to look up dev [%s]", errbuf);
1147 __STC_LOG_FUNC_EXIT__;
1148 return STC_ERROR_FAIL;
1151 STC_LOGD("Dev [%s]", dev);
1153 __STC_LOG_FUNC_EXIT__;
1154 return STC_ERROR_NONE;
1157 int stc_plugin_pcap_lookup_net(void)
1159 __STC_LOG_FUNC_ENTER__;
1162 char net[BUFF_SIZE_IP];
1163 char mask[BUFF_SIZE_IP];
1164 char errbuf[PCAP_ERRBUF_SIZE];
1169 dev = pcap_lookupdev(errbuf);
1171 STC_LOGE("Failed to look up dev [%s]", errbuf);
1172 __STC_LOG_FUNC_EXIT__;
1173 return STC_ERROR_FAIL;
1176 STC_LOGD("Dev [%s]", dev);
1178 ret = pcap_lookupnet(dev, &netp, &maskp, errbuf);
1180 STC_LOGE("Failed to look up net [%s]", errbuf);
1181 __STC_LOG_FUNC_EXIT__;
1182 return STC_ERROR_FAIL;
1185 inet_ntop(AF_INET, &netp, net, BUFF_SIZE_IP);
1186 STC_LOGD("Net [%s]", net);
1188 inet_ntop(AF_INET, &maskp, mask, BUFF_SIZE_IP);
1189 STC_LOGD("Mask [%s]", mask);
1191 __STC_LOG_FUNC_EXIT__;
1192 return STC_ERROR_NONE;
1195 int stc_plugin_pcap_find_alldevs(void)
1197 __STC_LOG_FUNC_ENTER__;
1199 char net[BUFF_SIZE_IP];
1200 char mask[BUFF_SIZE_IP];
1201 char errbuf[PCAP_ERRBUF_SIZE];
1202 pcap_if_t *alldevs = NULL;
1203 pcap_if_t *dev = NULL;
1207 if (pcap_findalldevs(&alldevs, errbuf) < 0 ||
1209 STC_LOGE("Failed to find all devs [%s]", errbuf);
1210 __STC_LOG_FUNC_EXIT__;
1211 return STC_ERROR_FAIL;
1214 for (dev = alldevs; dev; dev = dev->next) {
1215 STC_LOGD("Dev [%s]", dev->name);
1217 if (dev->description)
1218 STC_LOGD("Decs [%s]", dev->description);
1220 if (pcap_lookupnet(dev->name, &netp, &maskp, errbuf) == -1) {
1221 STC_LOGE("Failed to look up net [%s]", errbuf);
1225 inet_ntop(AF_INET, &netp, net, BUFF_SIZE_IP);
1226 STC_LOGD("Net [%s]", net);
1228 inet_ntop(AF_INET, &maskp, mask, BUFF_SIZE_IP);
1229 STC_LOGD("Mask [%s]", mask);
1232 pcap_freealldevs(alldevs);
1234 __STC_LOG_FUNC_EXIT__;
1235 return STC_ERROR_NONE;
1238 int stc_plugin_pcap_register_loop_pcap(const char *ifname,
1241 __STC_LOG_FUNC_ENTER__;
1243 stc_pcap_data_s *data;
1244 stc_pcap_data_s *lookup;
1245 char buf[MAX_IFACE_LENGTH];
1247 ret_value_msg_if(g_pcap_tables == NULL,
1249 "pcap tables is not initialized!");
1251 ret_value_msg_if(ifname == NULL,
1253 "Invalid parameter [ifname]");
1255 snprintf(buf, sizeof(buf), "%s_%d", ifname, group);
1257 lookup = g_hash_table_lookup(g_pcap_tables, buf);
1259 STC_LOGD("pcap loop already present");
1260 __STC_LOG_FUNC_EXIT__;
1261 return STC_ERROR_ALREADY_DATA;
1264 data = MALLOC0(stc_pcap_data_s, 1);
1266 STC_LOGE("data allocation failed");
1267 __STC_LOG_FUNC_EXIT__;
1268 return STC_ERROR_OUT_OF_MEMORY;
1271 data->name = g_strdup(ifname);
1272 data->group = group;
1273 data->thread = g_thread_new(buf, __pcap_thread_func, data);
1275 g_hash_table_insert(g_pcap_tables, g_strdup(buf), data);
1276 STC_LOGD("Successfully added pcap loop [%s]", buf);
1278 __STC_LOG_FUNC_EXIT__;
1279 return STC_ERROR_NONE;
1282 int stc_plugin_pcap_unregister_loop_pcap(const char *ifname,
1285 __STC_LOG_FUNC_ENTER__;
1287 stc_pcap_data_s *lookup;
1288 char buf[MAX_IFACE_LENGTH];
1290 ret_value_msg_if(g_pcap_tables == NULL,
1292 "pcap tables is not initialized!");
1294 ret_value_msg_if(ifname == NULL,
1296 "Invalid parameter [ifname]");
1298 snprintf(buf, sizeof(buf), "%s_%d", ifname, group);
1300 lookup = g_hash_table_lookup(g_pcap_tables, buf);
1302 STC_LOGE("pcap loop not found");
1303 __STC_LOG_FUNC_EXIT__;
1304 return STC_ERROR_NO_DATA;
1307 pcap_breakloop(lookup->handle);
1309 __STC_LOG_FUNC_EXIT__;
1310 return STC_ERROR_NONE;
1313 API stc_plugin_pcap_s stc_plugin_pcap = {
1314 .initialize_plugin =
1315 stc_plugin_pcap_initialize,
1316 .deinitialize_plugin =
1317 stc_plugin_pcap_deinitialize,
1319 stc_plugin_pcap_lookup_dev,
1321 stc_plugin_pcap_lookup_net,
1323 stc_plugin_pcap_find_alldevs,
1324 .register_loop_pcap =
1325 stc_plugin_pcap_register_loop_pcap,
1326 .unregister_loop_pcap =
1327 stc_plugin_pcap_unregister_loop_pcap