summaryrefslogtreecommitdiffstats
path: root/client/format.c
diff options
context:
space:
mode:
Diffstat (limited to 'client/format.c')
-rw-r--r--client/format.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/client/format.c b/client/format.c
new file mode 100644
index 0000000..6cc6057
--- /dev/null
+++ b/client/format.c
@@ -0,0 +1,216 @@
+#include <netinet/in.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+
+#include "format.h"
+
+icmp_entry_t icmp_type_table[] = {
+ { "Echo reply (PONG)", 0 },
+ { "Destination unreachable", 3 },
+ { "Source quench", 4 },
+ { "Redirect", 5 },
+ { "Echo request (PING)", 8 },
+ { "Router advertisement", 9 },
+ { "Timestamp request", 13 },
+ { "Information request", 15 },
+ { "Address mask reqeust", 17 },
+ { "Traceroute", 30 },
+ { "Domain name request", 37 },
+ { NULL, 0 }
+
+};
+
+icmp_entry_t icmp_code_table[] = {
+ { "Packet filtered", 13 },
+ { "Network unreachable", 0 },
+ { "Host unreachable", 1 },
+ { "Protocol unreachable", 2 },
+ { "Port unreachable", 3 },
+ { "Network unknown", 6 },
+ { "Host unknown", 7 },
+ { "Network prohibited", 9 },
+ { "Host prohibited", 10 },
+ { NULL, 0 }
+};
+
+gchar* icmp_type_str(guint8 t) {
+ gint i;
+ for (i = 0; icmp_type_table[i].name; i++)
+ if (icmp_type_table[i].value == t)
+ return icmp_type_table[i].name;
+
+ return NULL;
+}
+
+gchar* icmp_code_str(guint8 c) {
+ gint i;
+ for (i = 0; icmp_code_table[i].name; i++)
+ if (icmp_code_table[i].value == c)
+ return icmp_code_table[i].name;
+
+ return NULL;
+}
+
+void fill_icmp_menu(GtkOptionMenu *om, gboolean w, guint8 def) {
+ guint i, r = 0;
+ GtkMenu *m;
+ icmp_entry_t *table = w ? icmp_code_table : icmp_type_table;
+
+ m = GTK_MENU(gtk_menu_new());
+ for (i = 0; table[i].name; i++) {
+ GtkMenuItem *mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label(table[i].name));
+ g_object_set_data(G_OBJECT(mi), "icmp_value", GUINT_TO_POINTER((guint) table[i].value));
+ gtk_menu_shell_append(GTK_MENU_SHELL(m), GTK_WIDGET(mi));
+
+ if (table[i].value == def)
+ r = i;
+ }
+
+ gtk_option_menu_set_menu(om, GTK_WIDGET(m));
+ gtk_option_menu_set_history(om, r);
+}
+
+void set_icmp_menu_entry(GtkOptionMenu *om, gboolean w, guint8 def) {
+ guint r = 0, i;
+ icmp_entry_t *table = w ? icmp_code_table : icmp_type_table;
+
+ for (i = 0; table[i].name; i++)
+ if (table[i].value == def) {
+ r = i;
+ break;
+ }
+
+ gtk_option_menu_set_history(om, r);
+}
+
+
+gchar* format_ip_address(guint32 a) {
+ static gchar txt[256];
+
+ snprintf(txt, sizeof(txt), "%u.%u.%u.%u", a & 0xFF, (a >> 8) & 0xFF, (a >> 16) & 0xFF, a >> 24);
+ return txt;
+}
+
+
+gchar* format_hostname(guint32 a) {
+ static gchar txt[256];
+ struct hostent *he;
+
+ if ((he = gethostbyaddr(&a, 4, AF_INET))) {
+ g_strlcpy(txt, he->h_name, sizeof(txt));
+ return txt;
+ } else
+ return format_ip_address(a);
+}
+
+GList *fill_interface_list() {
+ GList *items = NULL;
+ int sock, n;
+ struct ifreq ifr[10];
+ struct ifconf ifc;
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return NULL;
+
+ ifc.ifc_req = ifr;
+ ifc.ifc_len = sizeof(ifr);
+
+ if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
+ goto finish;
+
+ for (n = 0 ; n < ifc.ifc_len/sizeof(struct ifreq); n++)
+ if (strcmp(ifr[n].ifr_name, "lo") != 0)
+ items = g_list_prepend(items, g_strdup(ifr[n].ifr_name));
+
+finish:
+ close(sock);
+ return items;
+}
+
+void free_interface_list(GList *l) {
+ while (l) {
+ gchar *s = (gchar*) l->data;
+ l = g_list_remove(l, s);
+ g_free(s);
+ }
+}
+
+
+gboolean is_broadcast(guint32 ip) {
+ int sock, n;
+ struct ifreq ifr[10];
+ struct ifconf ifc;
+ gboolean b = FALSE;
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return FALSE;
+
+ ifc.ifc_req = ifr;
+ ifc.ifc_len = sizeof(ifr);
+
+ if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
+ b = FALSE;
+ goto finish;
+ }
+
+ for (n = 0 ; n < ifc.ifc_len/sizeof(struct ifreq); n++) {
+ if (ioctl(sock, SIOCGIFBRDADDR, &ifc.ifc_req[n]) >= 0) {
+ if (ip == ((struct sockaddr_in*) &ifc.ifc_req[n].ifr_broadaddr)->sin_addr.s_addr) {
+ b = TRUE;
+ break;
+ }
+ }
+ }
+
+finish:
+ close(sock);
+ return b;
+}
+
+gchar* format_host_range(const gchar *ip, gint bits) {
+ struct in_addr a;
+ guint32 i, f, t, m;
+ static char txt[256];
+
+ if (!inet_aton(ip, &a))
+ return "<i>Invalid IP Address</i>";
+
+ if (bits > 32) bits = 32;
+ if (bits < 0) bits = 0;
+
+ if (bits == 32) {
+ snprintf(txt, sizeof(txt), "Single host %s", ip);
+ return txt;
+ } else if (bits == 0)
+ return "<i>Entire Internet</i>";
+
+ i = a.s_addr;
+
+ m = 0xFFFFFFFF << (32-bits);
+
+ f = i & htonl(m);
+ t = i | htonl(~m);
+
+ g_strlcpy(txt, inet_ntoa(*((struct in_addr*) &f)), sizeof(txt));
+ g_strlcat(txt, " - ", sizeof(txt));
+ g_strlcat(txt, inet_ntoa(*((struct in_addr*) &t)), sizeof(txt));
+
+ return txt;
+}
+
+gchar* format_verdict(verdict_t v, verdict_format_t t) {
+ switch (v) {
+ case VERDICT_QUERY: return t == FORMAT_USER ? "Query User" : "query";
+ case VERDICT_ACCEPT: return t == FORMAT_USER ? "Accept" : "accept";
+ case VERDICT_REJECT: return t == FORMAT_USER ? "Reject" : "reject";
+ case VERDICT_DROP: return t == FORMAT_USER ? "Drop" : "drop";
+ }
+
+ return "???";
+}