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 if (STC_DEBUG_LOG && STC_PCAP_LOG)
121 STC_LOGD("Flags[0x%02x] Stratum[%u] Poll[%u:%us] Precision[%u] "
122 "Root delay[%u.%06us] Root dispersion[%u.%06us] Ref ID[%s]",
123 ntp_h->flags, ntp_h->stratum, ntp_h->poll,
124 ntp_h->precision, 1 << ntp_h->precision,
125 ntohs(ntp_h->rootdelay.second),
126 __pcap_ntp_fraction_info(ntp_h->rootdelay.fraction),
127 ntohs(ntp_h->rootdisp.second),
128 __pcap_ntp_fraction_info(ntp_h->rootdisp.fraction),
131 if (STC_DEBUG_LOG && STC_PCAP_LOG)
132 STC_LOGD("Reference[%s] Origin[%s] Receive[%s] Transmit[%s]",
133 reftime, orgtime, rectime, xmttime);
136 static const char *__pcap_dhcp_client_id_info(uint8_t data)
141 case DHCP_CLIENT_ID_ETHERNET:
144 case DHCP_CLIENT_ID_IEEE802:
145 info = "IEEE 802 Networks";
147 case DHCP_CLIENT_ID_ARCNET:
150 case DHCP_CLIENT_ID_LOCALTALK:
153 case DHCP_CLIENT_ID_LOCALNET:
156 case DHCP_CLIENT_ID_SMDS:
159 case DHCP_CLIENT_ID_FRAMERELAY:
160 info = "Frame Relay";
162 case DHCP_CLIENT_ID_ATM1:
163 info = "ATM(Async Transfer Mode)";
165 case DHCP_CLIENT_ID_HDLC:
168 case DHCP_CLIENT_ID_FIBRECHANNEL:
169 info = "Fibre Channel";
171 case DHCP_CLIENT_ID_ATM2:
172 info = "ATM(Async Transfer Mode)";
174 case DHCP_CLIENT_ID_SERIALLINE:
175 info = "Serial Line";
185 static const char *__pcap_dhcp_msg_type_info(uint8_t type)
190 case DHCP_MSG_TYPE_DISCOVER:
193 case DHCP_MSG_TYPE_OFFER:
196 case DHCP_MSG_TYPE_REQUEST:
199 case DHCP_MSG_TYPE_DECLINE:
202 case DHCP_MSG_TYPE_ACK:
205 case DHCP_MSG_TYPE_NAK:
208 case DHCP_MSG_TYPE_RELEASE:
211 case DHCP_MSG_TYPE_INFORM:
222 static void __pcap_bootp_magic_info(uint32_t magic,
223 uint8_t *moption, u_int16_t len)
225 if (ntohl(magic) == BOOTP_MAGIC_DHCP) {
226 char buf[BOOTP_MOPTION_LEN];
227 uint8_t *opt = moption;
229 if (STC_DEBUG_LOG && STC_PCAP_LOG)
230 STC_LOGD("Magic cookie[DHCP]");
233 uint8_t tag = opt[0];
234 uint8_t length = opt[1];
235 uint8_t *data = &opt[2];
236 char addr[BUFF_SIZE_IP];
237 char host[BUFF_SIZE_HOST];
240 case DHCP_TAG_SUBNET_MASK:
241 inet_ntop(AF_INET, (struct in_addr *)data,
243 if (STC_DEBUG_LOG && STC_PCAP_LOG)
244 STC_LOGD("Subnet mask[%s]", addr);
246 case DHCP_TAG_ROUTER:
247 inet_ntop(AF_INET, (struct in_addr *)data,
249 if (STC_DEBUG_LOG && STC_PCAP_LOG)
250 STC_LOGD("Router[%s]", addr);
253 inet_ntop(AF_INET, (struct in_addr *)data,
255 if (STC_DEBUG_LOG && STC_PCAP_LOG)
256 STC_LOGD("Domain name server[%s]", addr);
258 case DHCP_TAG_HOST_NAME:
259 snprintf(buf, ((length < BOOTP_MOPTION_LEN) ?
260 (length + 1) : BOOTP_MOPTION_LEN), "%s", (char *)data);
261 if (STC_DEBUG_LOG && STC_PCAP_LOG)
262 STC_LOGD("Host name[%s]", buf);
264 case DHCP_TAG_REQUESTED_IP:
265 inet_ntop(AF_INET, (struct in_addr *)data,
267 if (STC_DEBUG_LOG && STC_PCAP_LOG)
268 STC_LOGD("Requested IP[%s]", addr);
270 case DHCP_TAG_IP_LEASE_TIME:
271 if (STC_DEBUG_LOG && STC_PCAP_LOG)
272 STC_LOGD("IP address lease time[%us]",
273 ntohl(*(uint32_t *)data));
275 case DHCP_TAG_MSG_TYPE:
276 if (STC_DEBUG_LOG && STC_PCAP_LOG)
277 STC_LOGD("DHCP message type[%u:%s]", *data,
278 __pcap_dhcp_msg_type_info(*data));
280 case DHCP_TAG_SERVER_ID:
281 inet_ntop(AF_INET, (struct in_addr *)data,
283 if (STC_DEBUG_LOG && STC_PCAP_LOG)
284 STC_LOGD("DHCP server identifier[%s]", addr);
286 case DHCP_TAG_MSG_SIZE:
287 if (STC_DEBUG_LOG && STC_PCAP_LOG)
288 STC_LOGD("Maximum DHCP message size[%u]",
289 ntohs(*(uint16_t *)data));
291 case DHCP_TAG_CLIENT_ID:
292 if (STC_DEBUG_LOG && STC_PCAP_LOG)
293 STC_LOGD("Client identifier HW type[0x%02x:%s]", *data,
294 __pcap_dhcp_client_id_info(*data));
295 if (*data == DHCP_CLIENT_ID_ETHERNET) {
297 ether_ntoa((const struct ether_addr *)&data[1]),
299 if (STC_DEBUG_LOG && STC_PCAP_LOG)
300 STC_LOGD("Client identifier MAC[%s]", host);
304 if (STC_DEBUG_LOG && STC_PCAP_LOG)
308 if (STC_DEBUG_LOG && STC_PCAP_LOG)
309 STC_LOGD("Unknown[%u]", tag);
319 static const char *__pcap_bootp_op_info(uint8_t op)
338 static void __pcap_bootp_info(const u_char *packet)
340 udp_t *udp_h = (udp_t *)(packet
341 + SIZE_ETHER_HEADER + SIZE_IP_HEADER);
342 bootp_t *bootp_h = (bootp_t *)(packet +
343 SIZE_ETHER_HEADER + SIZE_IP_HEADER + SIZE_UDP_HEADER);
344 char ciaddr[BUFF_SIZE_IP];
345 char yiaddr[BUFF_SIZE_IP];
346 char siaddr[BUFF_SIZE_IP];
347 char giaddr[BUFF_SIZE_IP];
348 char chaddr[BUFF_SIZE_HOST];
351 inet_ntop(AF_INET, &bootp_h->ciaddr, ciaddr, BUFF_SIZE_IP);
352 inet_ntop(AF_INET, &bootp_h->yiaddr, yiaddr, BUFF_SIZE_IP);
353 inet_ntop(AF_INET, &bootp_h->siaddr, siaddr, BUFF_SIZE_IP);
354 inet_ntop(AF_INET, &bootp_h->giaddr, giaddr, BUFF_SIZE_IP);
357 ether_ntoa((const struct ether_addr *)bootp_h->chaddr),
360 if (STC_DEBUG_LOG && STC_PCAP_LOG)
361 STC_LOGD("Message type[%u:%s] HW type[0x%02x] HW len[%u] Hops[%u] "
362 "Transaction ID[0x%08x] Seconds elapsed[%u] Flags[0x%04x]",
363 bootp_h->op, __pcap_bootp_op_info(bootp_h->op),
364 bootp_h->htype, bootp_h->hlen, bootp_h->hops,
365 ntohl(bootp_h->xid), ntohs(bootp_h->secs), ntohs(bootp_h->flags));
367 if (STC_DEBUG_LOG && STC_PCAP_LOG)
368 STC_LOGD("Client[%s] Your(client)[%s] Next server[%s] "
369 "Relay agent[%s] Client MAC[%s]",
370 ciaddr, yiaddr, siaddr, giaddr, chaddr);
372 len = ntohs(udp_h->len);
373 __pcap_bootp_magic_info(bootp_h->magic, bootp_h->moption, len);
376 static char *__pcap_dns_type_info(uint16_t type)
384 case DNS_QTYPE_CNAME:
398 static char *__pcap_dns_class_info(uint16_t class)
406 case DNS_QCLASS_CHAOS:
423 static uint8_t * __pcap_dns_name_info(uint8_t *dns_h,
424 uint8_t *data, u_char *name)
427 u_char *dname = name;
434 sec = (uint8_t *)dns_h +
435 (htons(*(uint16_t *)sec) & 0x3FFF);
443 if (dname - name + *sec + 1 > BUFF_SIZE_NAME - 1) {
448 memcpy(dname, sec + 1, *sec);
461 return (uint8_t *)nxt;
464 static void __pcap_dns_data_info(const u_char *packet)
466 dns_t *dns_h = (dns_t *)(packet +
467 SIZE_ETHER_HEADER + SIZE_IP_HEADER +
469 uint8_t *data = (uint8_t *)(packet +
470 SIZE_ETHER_HEADER + SIZE_IP_HEADER +
471 SIZE_UDP_HEADER + SIZE_DNS_HEADER);
472 uint16_t qdcount = ntohs(dns_h->questions);
473 uint16_t ancount = ntohs(dns_h->answerRR);
476 for (i = 0; i < qdcount; ++i) {
477 u_char name[BUFF_SIZE_NAME];
482 if (STC_DEBUG_LOG && STC_PCAP_LOG)
483 STC_LOGD("[Queries]");
486 data = __pcap_dns_name_info((uint8_t *)dns_h, data, name);
490 type = ntohs(*(uint16_t *)&data[0]);
491 class = ntohs(*(uint16_t *)&data[2]);
493 if (STC_DEBUG_LOG && STC_PCAP_LOG)
494 STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s]",
495 name, type, __pcap_dns_type_info(type),
496 class, __pcap_dns_class_info(class));
501 for (i = 0; i < ancount; ++i) {
502 u_char name[BUFF_SIZE_NAME];
503 u_char cname[BUFF_SIZE_NAME];
508 char ip[BUFF_SIZE_IP];
511 if (STC_DEBUG_LOG && STC_PCAP_LOG)
512 STC_LOGD("[Answers]");
515 data = __pcap_dns_name_info((uint8_t *)dns_h, data, name);
519 type = ntohs(*(uint16_t *)&data[0]);
520 class = ntohs(*(uint16_t *)&data[2]);
521 ttl = ntohl(*(uint32_t *)&data[4]);
522 length = ntohs(*(uint16_t *)&data[8]);
524 if (class == DNS_QCLASS_IN) {
527 inet_ntop(AF_INET, (struct in_addr *)&data[10],
529 if (STC_DEBUG_LOG && STC_PCAP_LOG)
530 STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s] "
531 "TTL[%u] Data length[%u] Address[%s]",
532 name, type, __pcap_dns_type_info(type),
533 class, __pcap_dns_class_info(class),
536 case DNS_QTYPE_CNAME:
537 __pcap_dns_name_info((uint8_t *)dns_h, &data[10], cname);
540 if (STC_DEBUG_LOG && STC_PCAP_LOG)
541 STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s] "
542 "TTL[%u] Data length[%u] CName[%s]",
543 name, type, __pcap_dns_type_info(type),
544 class, __pcap_dns_class_info(class),
550 if (STC_DEBUG_LOG && STC_PCAP_LOG)
551 STC_LOGD("Name[%s] Type[%u:%s] Class[0x%04x:%s] "
552 "TTL[%u] Data length[%u]",
553 name, type, __pcap_dns_type_info(type),
554 class, __pcap_dns_class_info(class),
560 data += (length + 10);
564 static void __pcap_dns_info(const u_char *packet)
566 dns_t *dns_h = (dns_t *)(packet +
567 SIZE_ETHER_HEADER + SIZE_IP_HEADER + SIZE_UDP_HEADER);
569 if (STC_DEBUG_LOG && STC_PCAP_LOG)
570 STC_LOGD("Transaction ID[0x%x] Flags[0x%x] Questions[%u] "
571 "Answer RRs[%u] Authority RRs[%u] Additional RRs[%u]",
572 ntohs(dns_h->id), ntohs(dns_h->flags),
573 ntohs(dns_h->questions), ntohs(dns_h->answerRR),
574 ntohs(dns_h->authorityRR), ntohs(dns_h->additionalRR));
576 __pcap_dns_data_info(packet);
579 static const char *__pcap_icmp_code_info(u_int8_t type, u_int8_t code)
584 case ICMP_DEST_UNREACH:
586 case ICMP_NET_UNREACH:
587 info = "Network Unreachable";
589 case ICMP_HOST_UNREACH:
590 info = "Host Unreachable";
592 case ICMP_PROT_UNREACH:
593 info = "Protocol Unreachable";
595 case ICMP_PORT_UNREACH:
596 info = "Port Unreachable";
598 case ICMP_FRAG_NEEDED:
599 info = "Fragmentation Needed/DF set";
602 info = "Source Route failed";
604 case ICMP_NET_UNKNOWN:
606 case ICMP_HOST_UNKNOWN:
608 case ICMP_HOST_ISOLATED:
614 case ICMP_NET_UNR_TOS:
616 case ICMP_HOST_UNR_TOS:
618 case ICMP_PKT_FILTERED:
619 info = "Packet filtered";
621 case ICMP_PREC_VIOLATION:
622 info = "Precedence violation";
624 case ICMP_PREC_CUTOFF:
625 info = "Precedence cut off";
635 info = "Redirect Net";
637 case ICMP_REDIR_HOST:
638 info = "Redirect Host";
640 case ICMP_REDIR_NETTOS:
641 info = "Redirect Net for TOS";
643 case ICMP_REDIR_HOSTTOS:
644 info = "Redirect Host for TOS";
651 case ICMP_TIME_EXCEEDED:
654 info = "TTL count exceeded";
656 case ICMP_EXC_FRAGTIME:
657 info = "Fragment Reass time exceeded";
672 static const char *__pcap_icmp_type_info(u_int8_t type)
680 case ICMP_DEST_UNREACH:
681 info = "Destination Unreachable";
683 case ICMP_SOURCE_QUENCH:
684 info = "Source Quench";
690 info = "Echo Request";
692 case ICMP_TIME_EXCEEDED:
693 info = "Time Exceeded";
695 case ICMP_PARAMETERPROB:
696 info = "Parameter Problem";
699 info = "Timestamp Request";
701 case ICMP_TIMESTAMPREPLY:
702 info = "Timestamp Reply";
704 case ICMP_INFO_REQUEST:
705 info = "Information Request";
707 case ICMP_INFO_REPLY:
708 info = "Information Reply";
711 info = "Address Mask Request";
713 case ICMP_ADDRESSREPLY:
714 info = "Address Mask Reply";
724 static void __pcap_icmp_info(const u_char *packet)
726 icmp_t *icmp_h = (icmp_t *)(packet +
727 SIZE_ETHER_HEADER + SIZE_IP_HEADER);
729 if (STC_DEBUG_LOG && STC_PCAP_LOG)
730 STC_LOGD("Type[%u:%s] Code[%u:%s] Checksum[0x%x]",
731 icmp_h->type, __pcap_icmp_type_info(icmp_h->type),
732 icmp_h->code, __pcap_icmp_code_info(icmp_h->type, icmp_h->code),
733 ntohs(icmp_h->checksum));
736 static void __pcap_tcp_info(const u_char *packet)
738 tcp_t *tcp_h = (tcp_t *)(packet +
739 SIZE_ETHER_HEADER + SIZE_IP_HEADER);
740 u_int16_t source = ntohs(tcp_h->source);
741 u_int16_t dest = ntohs(tcp_h->dest);
743 if (STC_DEBUG_LOG && STC_PCAP_LOG)
744 STC_LOGD("Source[%u] Destination[%u] Sequence[%u] "
745 "Acknowledgment seq[%u] Window size[%u] ",
746 ntohs(tcp_h->source), ntohs(tcp_h->dest),
747 ntohl(tcp_h->seq), ntohl(tcp_h->ack_seq),
748 ntohs(tcp_h->window));
750 if (STC_DEBUG_LOG && STC_PCAP_LOG)
751 STC_LOGD("Checksum[0x%x] URG[%u] ACK[%u] PUSH[%u] "
752 "RST[%u] SYN[%u] FIN[%u]",
754 tcp_h->urg, tcp_h->ack, tcp_h->psh,
755 tcp_h->rst, tcp_h->syn, tcp_h->fin);
757 if (IS_SRC_OR_DST_PORT(PORT_DNS))
758 __pcap_dns_info(packet);
761 static void __pcap_udp_info(const u_char *packet)
763 udp_t *udp_h = (udp_t *)(packet
764 + SIZE_ETHER_HEADER + SIZE_IP_HEADER);
765 u_int16_t source = ntohs(udp_h->source);
766 u_int16_t dest = ntohs(udp_h->dest);
768 if (STC_DEBUG_LOG && STC_PCAP_LOG)
769 STC_LOGD("Source[%u] Destination[%u] Len[%u] Checksum[0x%x]",
770 source, dest, ntohs(udp_h->len), ntohs(udp_h->check));
772 if (IS_SRC_OR_DST_PORT(PORT_DNS))
773 __pcap_dns_info(packet);
774 else if (IS_SRC_OR_DST_PORT(PORT_BOOTP_C) ||
775 IS_SRC_OR_DST_PORT(PORT_BOOTP_S))
776 __pcap_bootp_info(packet);
777 else if (IS_SRC_OR_DST_PORT(PORT_NTP))
778 __pcap_ntp_info(packet);
781 static const char *__pcap_eth_type_info(u_int16_t type)
795 case ETHERTYPE_REVARP:
798 case ETHERTYPE_LOOPBACK:
809 static const char *__pcap_arp_opcode_info(u_int16_t opcode)
834 static void __pcap_arp_info(const u_char *packet)
836 arp_t *arp_h = (arp_t *)(packet + SIZE_ETHER_HEADER);
837 u_int8_t *sha = (u_int8_t *)(packet +
838 SIZE_ETHER_HEADER + SIZE_ARP_HEADER);
839 u_int8_t *spa = (u_int8_t *)(sha + arp_h->ar_hln);
840 u_int8_t *tha = (u_int8_t *)(spa + arp_h->ar_pln);
841 u_int8_t *tpa = (u_int8_t *)(tha + arp_h->ar_hln);
842 u_int16_t ar_op = ntohs(arp_h->ar_op);
843 char sma[BUFF_SIZE_HOST];
844 char sia[BUFF_SIZE_IP];
845 char tma[BUFF_SIZE_HOST];
846 char tia[BUFF_SIZE_IP];
850 ether_ntoa((const struct ether_addr *)sha),
853 ether_ntoa((const struct ether_addr *)tha),
856 inet_ntop(AF_INET, (struct in_addr *)spa, sia, BUFF_SIZE_IP);
857 inet_ntop(AF_INET, (struct in_addr *)tpa, tia, BUFF_SIZE_IP);
859 ar_pro = ntohs(arp_h->ar_pro);
861 if (STC_DEBUG_LOG && STC_PCAP_LOG)
862 STC_LOGD("HW type[%u] Protocol type[0x%04x:%s] "
863 "HW size[%u] Protocol size[%u] Opcode[%u:%s] ",
864 ntohs(arp_h->ar_hrd), ar_pro,
865 __pcap_eth_type_info(ar_pro),
866 arp_h->ar_hln, arp_h->ar_pln,
867 ar_op, __pcap_arp_opcode_info(ar_op));
869 if (STC_DEBUG_LOG && STC_PCAP_LOG)
870 STC_LOGD("Sender MAC[%s] Sender IP[%s] "
871 "Target MAC[%s] Target IP[%s]",
875 static const char *__pcap_ip_protocol_info(u_int8_t p)
909 static void __pcap_ipv6_info(const u_char *packet)
911 ip6_t *ip6_h = (ip6_t *)(packet + SIZE_ETHER_HEADER);
912 char ip6_src[BUFF_SIZE_IP6];
913 char ip6_dst[BUFF_SIZE_IP6];
915 inet_ntop(AF_INET6, &ip6_h->ip6_src, ip6_src, BUFF_SIZE_IP6);
916 inet_ntop(AF_INET6, &ip6_h->ip6_dst, ip6_dst, BUFF_SIZE_IP6);
918 if (STC_DEBUG_LOG && STC_PCAP_LOG)
919 STC_LOGD("Flow[0x%08x] Payload len[%u] Next hdr[%u:%s] "
920 "Hop limit[%u] Source[%s] Destination[%s]",
921 ntohl(ip6_h->ip6_flow), ntohs(ip6_h->ip6_plen),
922 ip6_h->ip6_nxt, __pcap_ip_protocol_info(ip6_h->ip6_nxt),
923 ip6_h->ip6_hlim, ip6_src, ip6_dst);
925 switch (ip6_h->ip6_nxt) {
945 static void __pcap_ip_info(const u_char *packet)
947 ip_t *ip_h = (ip_t *)(packet + SIZE_ETHER_HEADER);
948 char ip_src[BUFF_SIZE_IP];
949 char ip_dst[BUFF_SIZE_IP];
951 inet_ntop(AF_INET, &ip_h->ip_src, ip_src, BUFF_SIZE_IP);
952 inet_ntop(AF_INET, &ip_h->ip_dst, ip_dst, BUFF_SIZE_IP);
954 if (STC_DEBUG_LOG && STC_PCAP_LOG)
955 STC_LOGD("Header len[%u] TOS[0x%02x] Total len[%u] "
956 "ID[0x%04x] Flags[0x%02x] TTL[%u] Protocol[%u:%s] "
957 "Checksum[0x%04x] Source[%s] Destination[%s]",
958 ip_h->ip_hl << 2, ip_h->ip_tos,
959 ntohs(ip_h->ip_len), ntohs(ip_h->ip_id),
960 (ntohs(ip_h->ip_off) & 0xe000) >> 13,
961 ip_h->ip_ttl, ip_h->ip_p,
962 __pcap_ip_protocol_info(ip_h->ip_p),
963 ntohs(ip_h->ip_sum), ip_src, ip_dst);
965 switch (ip_h->ip_p) {
967 __pcap_icmp_info(packet);
970 __pcap_tcp_info(packet);
973 __pcap_udp_info(packet);
980 static void __pcap_eth_info(const u_char *packet)
982 eth_t *eth_h = (eth_t *)packet;
983 u_int8_t *eth_shost = eth_h->ether_shost;
984 u_int8_t *eth_dhost = eth_h->ether_dhost;
985 char shost[BUFF_SIZE_HOST];
986 char dhost[BUFF_SIZE_HOST];
987 u_int16_t ether_type;
990 ether_ntoa((const struct ether_addr *)eth_shost),
994 ether_ntoa((const struct ether_addr *)eth_dhost),
997 ether_type = ntohs(eth_h->ether_type);
999 if (STC_DEBUG_LOG && STC_PCAP_LOG)
1000 STC_LOGD("Source[%s] Destination[%s] Type[0x%04x:%s]",
1001 shost, dhost, ether_type, __pcap_eth_type_info(ether_type));
1004 static void __pcap_fm_info(const struct pcap_pkthdr *pkthdr)
1008 struct timeval ts = pkthdr->ts;
1009 __time_t tv_sec = ts.tv_sec;
1010 __suseconds_t tv_usec = tv_usec;
1012 if (g_pcap_start_fm == false) {
1014 g_pcap_start_fm = true;
1017 curr = ctime((const time_t *)&tv_sec);
1019 curr[len - 1] = '\0';
1021 if (STC_DEBUG_LOG && STC_PCAP_LOG)
1022 STC_LOGD("Arrival time[%s] Timeval[%.06f] "
1023 "Frame len[%u] Capture len[%u]", curr,
1024 (float)((tv_sec - g_pcap_tv.tv_sec) * 1000000 +
1025 (tv_usec - g_pcap_tv.tv_usec)) / 1000000,
1026 pkthdr->len, pkthdr->caplen);
1029 static void __pcap_handler(u_char *param,
1030 const struct pcap_pkthdr *pkthdr,
1031 const u_char *packet) {
1033 unsigned short eth_type;
1034 /* int len = pkthdr->len; */
1036 __pcap_fm_info(pkthdr);
1038 eth_h = (eth_t *)packet;
1039 __pcap_eth_info(packet);
1041 eth_type = ntohs(eth_h->ether_type);
1044 __pcap_ip_info(packet);
1045 /* __pcap_data_info(pcaket, len); */
1047 case ETHERTYPE_IPV6:
1048 __pcap_ipv6_info(packet);
1051 case ETHERTYPE_REVARP:
1052 __pcap_arp_info(packet);
1054 case ETHERTYPE_LOOPBACK:
1061 static gboolean __pcap_thread_source_func(gpointer data)
1063 char buf[MAX_IFACE_LENGTH];
1064 stc_pcap_data_s *lookup;
1065 stc_pcap_data_s *pcap_data = (stc_pcap_data_s *)data;
1067 g_pcap_tv.tv_sec = 0;
1068 g_pcap_tv.tv_usec = 0;
1069 g_pcap_start_fm = false;
1071 if (g_pcap_tables == NULL)
1074 snprintf(buf, sizeof(buf), "%s_%d",
1075 pcap_data->name, pcap_data->group);
1077 lookup = g_hash_table_lookup(g_pcap_tables, buf);
1079 STC_LOGE("pcap loop not found");
1083 g_hash_table_remove(g_pcap_tables, buf);
1084 STC_LOGD("Successfully removed pcap loop [%s]", buf);
1089 static gpointer __pcap_thread_func(gpointer data)
1091 __STC_LOG_FUNC_ENTER__;
1093 char errbuf[PCAP_ERRBUF_SIZE];
1094 pcap_if_t *alldevs = NULL;
1095 pcap_if_t *dev = NULL;
1097 GSource *source = NULL;
1098 GMainContext *context = NULL;
1099 stc_pcap_data_s *pcap_data = (stc_pcap_data_s *)data;
1101 if (pcap_findalldevs(&alldevs, errbuf) < 0 ||
1103 STC_LOGE("Failed to find all devs [%s]", errbuf);
1107 for (dev = alldevs; dev; dev = dev->next) {
1108 if (g_strcmp0(dev->name, pcap_data->name) == 0) {
1109 name = g_strdup(dev->name);
1114 pcap_freealldevs(alldevs);
1117 STC_LOGE("Failed to find dev [%s]", pcap_data->name);
1121 STC_LOGD("Pcap source dev [%s]", name);
1123 pcap_data->handle = pcap_open_live(name, 65535, 1, 1000, errbuf);
1124 if (pcap_data->handle == NULL) {
1125 STC_LOGE("Failed to open live [%s]", errbuf);
1129 pcap_loop(pcap_data->handle, 0, __pcap_handler, NULL);
1131 pcap_close(pcap_data->handle);
1136 context = g_main_context_default();
1138 source = g_idle_source_new();
1140 g_source_set_callback(source,
1141 __pcap_thread_source_func, pcap_data, NULL);
1142 g_source_attach(source, context);
1144 g_source_unref(source);
1146 __STC_LOG_FUNC_EXIT__;
1150 int stc_plugin_pcap_initialize(void)
1152 __STC_LOG_FUNC_ENTER__;
1154 g_pcap_tables = g_hash_table_new_full(g_str_hash,
1155 g_str_equal, g_free, __pcap_data_free);
1157 __STC_LOG_FUNC_EXIT__;
1158 return STC_ERROR_NONE;
1161 int stc_plugin_pcap_deinitialize(void)
1163 __STC_LOG_FUNC_ENTER__;
1165 if (g_pcap_tables) {
1166 g_hash_table_destroy(g_pcap_tables);
1167 g_pcap_tables = NULL;
1170 __STC_LOG_FUNC_EXIT__;
1171 return STC_ERROR_NONE;
1174 int stc_plugin_pcap_lookup_dev(void)
1176 __STC_LOG_FUNC_ENTER__;
1179 char errbuf[PCAP_ERRBUF_SIZE];
1181 dev = pcap_lookupdev(errbuf);
1183 STC_LOGE("Failed to look up dev [%s]", errbuf);
1184 __STC_LOG_FUNC_EXIT__;
1185 return STC_ERROR_FAIL;
1188 STC_LOGD("Dev [%s]", dev);
1190 __STC_LOG_FUNC_EXIT__;
1191 return STC_ERROR_NONE;
1194 int stc_plugin_pcap_lookup_net(void)
1196 __STC_LOG_FUNC_ENTER__;
1199 char net[BUFF_SIZE_IP];
1200 char mask[BUFF_SIZE_IP];
1201 char errbuf[PCAP_ERRBUF_SIZE];
1206 dev = pcap_lookupdev(errbuf);
1208 STC_LOGE("Failed to look up dev [%s]", errbuf);
1209 __STC_LOG_FUNC_EXIT__;
1210 return STC_ERROR_FAIL;
1213 STC_LOGD("Dev [%s]", dev);
1215 ret = pcap_lookupnet(dev, &netp, &maskp, errbuf);
1217 STC_LOGE("Failed to look up net [%s]", errbuf);
1218 __STC_LOG_FUNC_EXIT__;
1219 return STC_ERROR_FAIL;
1222 inet_ntop(AF_INET, &netp, net, BUFF_SIZE_IP);
1223 STC_LOGD("Net [%s]", net);
1225 inet_ntop(AF_INET, &maskp, mask, BUFF_SIZE_IP);
1226 STC_LOGD("Mask [%s]", mask);
1228 __STC_LOG_FUNC_EXIT__;
1229 return STC_ERROR_NONE;
1232 int stc_plugin_pcap_find_alldevs(void)
1234 __STC_LOG_FUNC_ENTER__;
1236 char net[BUFF_SIZE_IP];
1237 char mask[BUFF_SIZE_IP];
1238 char errbuf[PCAP_ERRBUF_SIZE];
1239 pcap_if_t *alldevs = NULL;
1240 pcap_if_t *dev = NULL;
1244 if (pcap_findalldevs(&alldevs, errbuf) < 0 ||
1246 STC_LOGE("Failed to find all devs [%s]", errbuf);
1247 __STC_LOG_FUNC_EXIT__;
1248 return STC_ERROR_FAIL;
1251 for (dev = alldevs; dev; dev = dev->next) {
1252 STC_LOGD("Dev [%s]", dev->name);
1254 if (dev->description)
1255 STC_LOGD("Decs [%s]", dev->description);
1257 if (pcap_lookupnet(dev->name, &netp, &maskp, errbuf) == -1) {
1258 STC_LOGE("Failed to look up net [%s]", errbuf);
1262 inet_ntop(AF_INET, &netp, net, BUFF_SIZE_IP);
1263 STC_LOGD("Net [%s]", net);
1265 inet_ntop(AF_INET, &maskp, mask, BUFF_SIZE_IP);
1266 STC_LOGD("Mask [%s]", mask);
1269 pcap_freealldevs(alldevs);
1271 __STC_LOG_FUNC_EXIT__;
1272 return STC_ERROR_NONE;
1275 int stc_plugin_pcap_register_loop_pcap(const char *ifname,
1278 __STC_LOG_FUNC_ENTER__;
1280 stc_pcap_data_s *data;
1281 stc_pcap_data_s *lookup;
1282 char buf[MAX_IFACE_LENGTH];
1284 ret_value_msg_if(g_pcap_tables == NULL,
1286 "pcap tables is not initialized!");
1288 ret_value_msg_if(ifname == NULL,
1290 "Invalid parameter [ifname]");
1292 snprintf(buf, sizeof(buf), "%s_%d", ifname, group);
1294 lookup = g_hash_table_lookup(g_pcap_tables, buf);
1296 STC_LOGD("pcap loop already present");
1297 __STC_LOG_FUNC_EXIT__;
1298 return STC_ERROR_ALREADY_DATA;
1301 data = MALLOC0(stc_pcap_data_s, 1);
1303 STC_LOGE("data allocation failed");
1304 __STC_LOG_FUNC_EXIT__;
1305 return STC_ERROR_OUT_OF_MEMORY;
1308 data->name = g_strdup(ifname);
1309 data->group = group;
1310 data->thread = g_thread_new(buf, __pcap_thread_func, data);
1312 g_hash_table_insert(g_pcap_tables, g_strdup(buf), data);
1313 STC_LOGD("Successfully added pcap loop [%s]", buf);
1315 __STC_LOG_FUNC_EXIT__;
1316 return STC_ERROR_NONE;
1319 int stc_plugin_pcap_unregister_loop_pcap(const char *ifname,
1322 __STC_LOG_FUNC_ENTER__;
1324 stc_pcap_data_s *lookup;
1325 char buf[MAX_IFACE_LENGTH];
1327 ret_value_msg_if(g_pcap_tables == NULL,
1329 "pcap tables is not initialized!");
1331 ret_value_msg_if(ifname == NULL,
1333 "Invalid parameter [ifname]");
1335 snprintf(buf, sizeof(buf), "%s_%d", ifname, group);
1337 lookup = g_hash_table_lookup(g_pcap_tables, buf);
1339 STC_LOGE("pcap loop not found");
1340 __STC_LOG_FUNC_EXIT__;
1341 return STC_ERROR_NO_DATA;
1344 pcap_breakloop(lookup->handle);
1346 __STC_LOG_FUNC_EXIT__;
1347 return STC_ERROR_NONE;
1350 API stc_plugin_pcap_s stc_plugin_pcap = {
1351 .initialize_plugin =
1352 stc_plugin_pcap_initialize,
1353 .deinitialize_plugin =
1354 stc_plugin_pcap_deinitialize,
1356 stc_plugin_pcap_lookup_dev,
1358 stc_plugin_pcap_lookup_net,
1360 stc_plugin_pcap_find_alldevs,
1361 .register_loop_pcap =
1362 stc_plugin_pcap_register_loop_pcap,
1363 .unregister_loop_pcap =
1364 stc_plugin_pcap_unregister_loop_pcap