/*
 *  $Id: gtk_cp.c,v 1.1.1.1 1999/04/26 22:44:54 route Exp $
 *
 *  Firewalk
 *  gtk code
 *  gtk_cp.c - firewalk gtk control panel routines
 *
 *  Copyright (c) 1999 Mike D. Schiffman <mike@infonexus.com>
 *  Copyright (c) 1998 Mike D. Schiffman <mds@es2.net>
 *  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#if (HAVE_CONFIG_H)
#include "./config.h"
#endif
#include "./gtk_main.h"
#include "./gtk_util.h"
#include "./gtk_cb.h"
#include "./gtk_cp.h"
#include "./gtk_pack.h"
#include "./main.h"
#include "./packet.h"
#include "./gtk_itemfactory.h"
#include "./firewalk.h"
#include "./version.h"

/*
 *  This code is heavily commented for the benefit of the programmer who
 *  wants to learn GTK.  Note that there is no error checking done on any
 *  GTK calls.  None of the GTK code I've looked at (tutorial example code,
 *  GNU info documentation sample code, the example code that came with the
 *  library, and finally, several GTK-based applications) check for errors.
 *  I'm not sure why people don't check the return values of gtk_* calls,
 *  but they don't.  So I don't.
 */

void
gtk_cp()
{
    GtkWidget *main_window, *packing_grid, *button_box;
    GtkWidget *set_button, *close_button, *rb_vbox, *rb_frame;
    GtkWidget *i_port_label, *red_cnt_label, *s_port_label, *ttl_label;
    GtkWidget *xv_label, *wp_label, *rp_label, *plist_entry_label;
    GtkTooltips *set_button_tt, *close_button_tt;
    GtkAdjustment *adj;
    GSList *grp;

    /*
     *  Get the main window and set the borderwidth.
     */
    main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_container_border_width(GTK_CONTAINER(main_window), BORDER_WIDTH_1);

    /*
     *  Setup the signal callback for the delete_event event and the destroy
     *  event for our main window.
     */
    gtk_signal_connect(GTK_OBJECT(main_window), "delete_event",
        GTK_SIGNAL_FUNC(gtk_quit_cp_cb), NULL);
    gtk_signal_connect(GTK_OBJECT(main_window), "destroy",
        GTK_SIGNAL_FUNC(gtk_quit_cp_cb), NULL);

    /*
     *  Set textbox title.
     */
    gtk_window_set_title(GTK_WINDOW(main_window), "Firewalk Control Panel");

    /*
     *  The packing grid is how we arrange widgets on the screen.
     */
    packing_grid = gtk_table_new(100, 100, FALSE);
    gtk_container_border_width(GTK_CONTAINER(packing_grid), BORDER_WIDTH_0);
    gtk_container_add(GTK_CONTAINER(main_window), packing_grid);

    /*
     *  Source port spinbutton.
     */
    adj = (GtkAdjustment *)gtk_adjustment_new(fp->sport, PORT_MIN,
        PORT_MAX, 1, 10, 0);
    gtk_do_spin_button(adj, &gp->s_port_sb, &s_port_label, "Source port");
    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->s_port_sb,      /* widget we are packing */
        0,                  /* left grid coordinate */
        1,                  /* rite grid coordinate */
        0,                  /* top grid coordinate */
        1,                  /* bottom grid coordinate */
        0,
        0,                  /* but not the Y */
        0,                  /* no X padding */
        5);                 /* a smidge of Y padding */
    gtk_table_attach(GTK_TABLE(packing_grid),
        s_port_label,
        1,
        2,
        0,
        1,
        0,
        0,
        0,
        5);

    /*
     *  Initial ramping port spinbutton.
     */
    adj = (GtkAdjustment *)gtk_adjustment_new(fp->init_probe_port, PORT_MIN,
        PORT_MAX, 1, 10, 0);
    gtk_do_spin_button(adj, &gp->i_port_sb, &i_port_label,
        "Initial ramping port");
    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->i_port_sb,
        2,
        3,
        0,
        1,
        0,
        0,
        0,
        5);
    gtk_table_attach(GTK_TABLE(packing_grid),
        i_port_label,
        3,
        4,
        0,
        1,
        0,
        0,
        0,
        5);

    /*
     *  Network writing pause spinbutton.
     */
    adj = (GtkAdjustment *)gtk_adjustment_new(fp->write_pause, WRITE_PAUSE_MIN,
        WRITE_PAUSE_MAX, 1, 10, 0);
    gtk_do_spin_button(adj, &gp->wp_sb, &wp_label,
        "Network writing pause");
    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->wp_sb,
        0,
        1,
        1,
        2,
        0,
        0,
        0,
        5);
    gtk_table_attach(GTK_TABLE(packing_grid),
        wp_label,
        1,
        2,
        1,
        2,
        0,
        0,
        0,
        5);

    /*
     *  Redundancy count spinbutton.
     */
    adj = (GtkAdjustment *)gtk_adjustment_new(fp->red_cnt, RED_CNT_MIN,
        RED_CNT_MAX, 1, 2, 0);
    gtk_do_spin_button(adj, &gp->red_cnt_sb, &red_cnt_label,
        "Redundancy Count");
    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->red_cnt_sb,
        2,
        3,
        1,
        2,
        0,
        0,
        0,
        5);
    gtk_table_attach(GTK_TABLE(packing_grid),
        red_cnt_label,
        3,
        4,
        1,
        2,
        0,
        0,
        0,
        5);

    /*
     *  Read timeout pause spinbutton.
     */
    adj = (GtkAdjustment *)gtk_adjustment_new(fp->pcap_timeout,
        PCAP_TIMEOUT_MIN, PCAP_TIMEOUT_MAX, 1, 10, 0);
    gtk_do_spin_button(adj, &gp->rp_sb, &rp_label,
        "Network timeout pause");
    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->rp_sb,
        0,
        1,
        3,
        4,
        0,
        0,
        0,
        5);
    gtk_table_attach(GTK_TABLE(packing_grid),
        rp_label,
        1,
        2,
        3,
        4,
        0,
        0,
        0,
        5);

    /*
     *  Initial TTL spinbutton.
     */
    adj = (GtkAdjustment *)gtk_adjustment_new(fp->ttl, IP_HOP_MIN, IP_HOP_MAX,
        1, 5, 0);
    gtk_do_spin_button(adj, &gp->ttl_sb, &ttl_label,
        "Initial IP TTL");
    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->ttl_sb,
        2,
        3,
        3,
        4,
        0,
        0,
        0,
        5);
    gtk_table_attach(GTK_TABLE(packing_grid),
        ttl_label,
        3,
        4,
        3,
        4,
        0,
        0,
        0,
        5);

    /*
     *  Expire vector spinbutton.
     */
    adj = (GtkAdjustment *)gtk_adjustment_new(fp->xv, XV_MIN, XV_MAX, 1, 2,
        0);
    gtk_do_spin_button(adj, &gp->xv_sb, &xv_label, "Expire vector");
    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->xv_sb,
        0,
        1,
        4,
        5,
        0,
        0,
        0,
        5);
    gtk_table_attach(GTK_TABLE(packing_grid),
        xv_label,
        1,
        2,
        4,
        5,
        0,
        0,
        0,
        5);

    /*
     *  Port list entry
     */
    gp->plist_entry = gtk_entry_new_with_max_length(ENTRY_SIZE);
    gtk_entry_set_text(GTK_ENTRY(gp->plist_entry),
        dump_port_list_as_string(fp->plist));
    plist_entry_label = gtk_label_new("port scan list");
    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->plist_entry,
        2,
        3,
        4,
        5,
        0,
        0,
        0,
        5);
    gtk_table_attach(GTK_TABLE(packing_grid),
        plist_entry_label,
        3,
        4,
        4,
        5,
        0,
        0,
        0,
        5);

    /*
     *  DNS resolver checkbutton.
     */
    gp->dns_cb = gtk_check_button_new_with_label("Resolve IP addresses");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gp->dns_cb),
        fp->use_name ? TRUE : FALSE);

    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->dns_cb,
        0,
        9,
        10,
        11,
        GTK_FILL,
        0,
        0,
        0);

    /*
     *  Quiet mode checkbutton.
     */
    gp->quiet_cb = gtk_check_button_new_with_label("Quiet mode");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gp->quiet_cb),
        fp->quiet ? TRUE : FALSE);

    gtk_table_attach(GTK_TABLE(packing_grid), gp->quiet_cb,
        0,
        9,
        12,
        13,
        GTK_FILL,
        0,
        0,
        0);


    /*
     *  File output checkbutton.
     */
    gp->file_cb = gtk_check_button_new_with_label("Output to file");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gp->file_cb),
        fp->output_file ? TRUE : FALSE);
    gtk_signal_connect(GTK_OBJECT(gp->file_cb), "clicked",
        GTK_SIGNAL_FUNC(gtk_fsb_cb), NULL);

    gtk_table_attach(GTK_TABLE(packing_grid),
        gp->file_cb,
        0,
        9,
        14,
        15,
        GTK_FILL,
        0,
        0,
        0);

    /*
     *  Firewalking protocol radiobutton, vbox, and labeled frame.
     */
    gp->rb = gtk_radio_button_new_with_label(NULL, "UDP");
    rb_frame = gtk_frame_new("Firewalk scanning protocol");
    rb_vbox = gtk_vbox_new(FALSE, 0);
    gtk_widget_set_usize(GTK_WIDGET(rb_frame), 163, 80);
    gtk_box_pack_start(GTK_BOX(rb_vbox), gp->rb, FALSE, FALSE, 0);

    grp = gtk_radio_button_group(GTK_RADIO_BUTTON(gp->rb));
    gp->rb = gtk_radio_button_new_with_label(grp, "TCP");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gp->rb),
        fp->protocol == IPPROTO_UDP ? FALSE : TRUE);
    gtk_box_pack_start(GTK_BOX(rb_vbox), gp->rb, FALSE, FALSE, 0);

    gtk_table_attach(GTK_TABLE(packing_grid),
        rb_vbox,
        0,
        9,
        20,
        21,
        GTK_FILL,
        0,
        0,
        0);
    gtk_table_attach(GTK_TABLE(packing_grid),
        rb_frame,
        0,
        9,
        20,
        21,
        GTK_FILL,
        0,
        0,
        0);

    /*
     *  Initialize a button box.
     */
    button_box = gtk_hbutton_box_new();
    gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_END);

    /*
     *  Create our `set` button and associate tooltip.
     */
    set_button = gtk_button_new_with_label("Set Parameters");
    gtk_signal_connect_object(GTK_OBJECT(set_button), "clicked",
        GTK_SIGNAL_FUNC(gtk_set_cp_cb), GTK_OBJECT(main_window));
    GTK_WIDGET_SET_FLAGS(set_button, GTK_CAN_DEFAULT);
    gtk_widget_grab_default(set_button);
    set_button_tt = gtk_tooltips_new();
    gtk_tooltips_set_tip(set_button_tt, set_button,
        "You probably know what you're doing", NULL);

    gtk_table_attach(GTK_TABLE(packing_grid),
        set_button,
        0,
        9,
        23,
        24,
        GTK_FILL,
        0,
        0,
        0);
    /*
     *  Create our `close` button and associate tooltip.
     */
    close_button = gtk_button_new_with_label("Close");
    gtk_signal_connect_object(GTK_OBJECT(close_button), "clicked",
        GTK_SIGNAL_FUNC(gtk_quit_cp_cb), GTK_OBJECT(main_window));
    GTK_WIDGET_SET_FLAGS(close_button, GTK_CAN_DEFAULT);
    gtk_widget_grab_default(close_button);
    close_button_tt = gtk_tooltips_new();
    gtk_tooltips_set_tip(close_button_tt, close_button,
        "Let's pretend like this never happened", NULL);

    gtk_table_attach(GTK_TABLE(packing_grid),
        close_button,
        0,
        9,
        24,
        25,
        GTK_FILL,
        0,
        0,
        0);

    gtk_widget_show_all(main_window);
}


/* EOF */
