5e397feb1519aca6c283f797e0d38ccc57106f89
[metze/wireshark/wip.git] / ui / cli / tap-hosts.c
1 /* tap-hosts.c
2  *
3  * $Id$
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 /* Dump our collected IPv4- and IPv6-to-hostname mappings */
25
26 #include "config.h"
27
28 #include <stdio.h>
29
30 #include <string.h>
31
32 #include "globals.h"
33
34 #include <epan/packet.h>
35 #include <cfile.h>
36 #include <epan/proto.h>
37 #include <epan/tap.h>
38 #include <epan/stat_cmd_args.h>
39 #include <epan/addr_resolv.h>
40
41 /* Needed for addrinfo */
42 #ifdef HAVE_SYS_TYPES_H
43 # include <sys/types.h>
44 #endif
45
46 #ifdef HAVE_SYS_SOCKET_H
47 #include <sys/socket.h>
48 #endif
49
50 #ifdef HAVE_ARPA_INET_H
51 #include <arpa/inet.h>
52 #endif
53
54 #ifdef HAVE_NETINET_IN_H
55 # include <netinet/in.h>
56 #endif
57
58 #ifdef HAVE_NETDB_H
59 # include <netdb.h>
60 #endif
61
62 #ifdef HAVE_WINSOCK2_H
63 # include <winsock2.h>
64 #endif
65
66 #if defined(_WIN32) && defined(INET6)
67 # include <ws2tcpip.h>
68 #endif
69
70 #ifdef NEED_INET_V6DEFS_H
71 # include "wsutil/inet_v6defs.h"
72 #endif
73
74
75 gboolean dump_v4 = FALSE;
76 gboolean dump_v6 = FALSE;
77
78 #define TAP_NAME "hosts"
79
80 #define HOSTNAME_POS 48
81 #define ADDRSTRLEN 46 /* Covers IPv4 & IPv6 */
82 static void
83 hosts_draw(void *dummy _U_)
84 {
85         struct addrinfo *ai;
86         struct sockaddr_in *sa4;
87         struct sockaddr_in6 *sa6;
88         char   addr_str[ADDRSTRLEN];
89         int i, tab_count;
90
91         printf("# TShark hosts output\n");
92         printf("#\n");
93         printf("# Host data gathered from %s\n", cfile.filename);
94         printf("\n");
95
96         /* Dump the v4 addresses first, then v6 */
97         for (ai = get_addrinfo_list(); ai; ai = ai->ai_next) {
98                 if (!dump_v4 || ai->ai_family != AF_INET) {
99                         continue;
100                 }
101
102                 sa4 = (struct sockaddr_in *)(void *)ai->ai_addr;
103                 if (inet_ntop(AF_INET, &(sa4->sin_addr.s_addr), addr_str, ADDRSTRLEN)) {
104                         tab_count = (HOSTNAME_POS - (int)strlen(addr_str)) / 8;
105                         printf("%s", addr_str);
106                         for (i = 0; i < tab_count; i++)
107                                 printf("\t");
108                         printf("%s\n", ai->ai_canonname);
109                 }
110         }
111
112
113         for (ai = get_addrinfo_list(); ai; ai = ai->ai_next) {
114                 if (!dump_v6 || ai->ai_family != AF_INET6) {
115                         continue;
116                 }
117
118                 sa6 = (struct sockaddr_in6 *)(void *)ai->ai_addr;
119                 if (inet_ntop(AF_INET6, sa6->sin6_addr.s6_addr, addr_str, ADDRSTRLEN)) {
120                         tab_count = (HOSTNAME_POS - (int)strlen(addr_str)) / 8;
121                         printf("%s", addr_str);
122                         for (i = 0; i < tab_count; i++)
123                                 printf("\t");
124                         printf("%s\n", ai->ai_canonname);
125                 }
126         }
127 }
128
129
130 static void
131 hosts_init(const char *optarg, void* userdata _U_)
132 {
133         GString *error_string;
134         gchar **tokens;
135         gint opt_count;
136
137         dump_v4 = FALSE;
138         dump_v6 = FALSE;
139
140         if(strcmp(TAP_NAME, optarg)==0) {
141                 /* No arguments; dump everything */
142                 dump_v4 = TRUE;
143                 dump_v6 = TRUE;
144         } else {
145                 tokens = g_strsplit(optarg,",", 0);
146                 opt_count=0;
147                 while (tokens[opt_count]) {
148                         if (strcmp("ipv4", tokens[opt_count]) == 0) {
149                                 dump_v4 = TRUE;
150                         } else if (strcmp("ipv6", tokens[opt_count]) == 0) {
151                                 dump_v6 = TRUE;
152                         } else if (opt_count > 0) {
153                                 fprintf(stderr, "tshark: invalid \"-z " TAP_NAME "[,ipv4|ipv6]\" argument\n");
154                                 exit(1);
155                         }
156                         opt_count++;
157                 }
158                 g_strfreev(tokens);
159         }
160
161         error_string=register_tap_listener("frame", NULL, NULL, TL_REQUIRES_PROTO_TREE,
162                                            NULL, NULL, hosts_draw);
163         if(error_string){
164                 /* error, we failed to attach to the tap. clean up */
165                 fprintf(stderr, "tshark: Couldn't register " TAP_NAME " tap: %s\n",
166                     error_string->str);
167                 g_string_free(error_string, TRUE);
168                 exit(1);
169         }
170 }
171
172 void
173 register_tap_listener_hosts(void)
174 {
175         register_stat_cmd_arg(TAP_NAME, hosts_init, NULL);
176 }
177