Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / bootstrap

GUI Modeling in Perl/Tk Using Composite Design Pattern

5.00/5 (1 vote)
14 Dec 2018CPOL12 min read 8.4K   64  
This document is spanned over two sections DESIGN and EXAMPLE. DESIGN talks about generic way to develop GUI for a command line utility through composite design pattern and EXAMPLE is about using the above GUI design formula to develop DataPool ,DoS security tool, GUI.

Table of Contents

  • 1. Introduction
  • 2. DESIGN
    • 2.1 Design detail
      • 2.1.1 Description of components
        • 2.1.1.1 Resource file
        • 2.1.1.2 Widget specific files
        • 2.1.1.3 Miscellaneous files
        • 2.1.1.4 Main program
      • 2.2 Program execution
      • 2.3 Target directory structure
        • 2.3.1 Application with interfaces
  • 3. EXAMPLE (DataPool DoS tool)
    • 3.1 About tool
    • 3.2 About GUI proposal
      • 3.2.1 Main Window
        • 3.2.1.1 Frame hierarchy and elements
        • 3.2.1.2 Menu Look
        • 3.2.1.3 Detached console look
    • 3.3 Target directory structure
    • 3.4 Tool installation
    • 3.5 GUI Snapshots
      • 3.5.1 Main Window (LINUX & WINDOWS XP)
      • 3.5.2 Console dissociation in a new Window
      • 3.5.3 Optionals removal from Main Window
      • 3.5.4 Opening File to read
  • 4. Summary
  • 5. References

1. Introduction

Generic way of developing Graphical User Interface(GUI) is a concept where it provides an idea to generate graphical User Interface using set of some predefined rules (i.e config file) and libraries. This framework can also be used in generating graphical model to some command line utility. Graphical rules are declared in configuration file (resource file) and editing configuration file (adding GUI elements/removing GUI elements/changing GUI elements) would change the GUI look and feel at run time. Perl/Tk code should remain untouched.

This document is spanned over two sections DESIGN and EXAMPLE. DESIGN talks about generic way to develop GUI for a command line utility through composite design pattern and EXAMPLE is about using the above GUI design formula to develop DataPool ,DoS security tool, GUI.  

2. DESIGN (SECTION)

2.1 Design detail

Generic GUI design architecture is distributed among four components.

  1. Resource file - File containing declaration for graphical layouts. Typically it will be hierarchical where one graphical element contain others. Ex. A frame widget can contain a frame widget, toplevel widget or any leaf widgets(listbox, editbox, label etc).
  2. Widget specific package - Wrapper over Perl/Tk widget classes, in order to interpret graphical layouts (parsed from resource file) and then create (handle) widgets dynamically using Perl/Tk APIs. Ex. DtFrame.pm(for Frame widget), DtToplevel.pm(for Toplevel widgets), DtMenu.pm(for Menu widgets) etc. Dt is prefixed to make it different from real widget class name.
  3. Miscellaneous/Util package - Miscellaneous/library subroutines, Ex. enablewidget, disablewidget etc...
  4. Main program - Mediator program to call widget wrapper modules to parse resource file to create the actual widget. It then does actual work of handling events.
                         ---
                         | |
                         ------------
                         |   Util   |
                         |          |
                         ------------
                              ^ |
                              | |
                              | |
                              | |
                              | |
                              | |
                              | |
---                       --- | |                       ---
| |                       | | | v                       | |
---------- <<create/      ----------- <<read res. to    --------------
|        | manipulate/    |Widget   |------------------>|  Resource  |
|  Main  |--------------->|Wrapper  | create widget>>   |(Persistent)|
|        | destroy        |         |<------------------|            |
---------- widgets>>      -----------        <<callback --------------
                                          registration>>
component diagram
<>---------  Aggregation
<>.........  Composition
 ----------> Dependency
/ \
 |   Generalization
 |
                                     ---------            ----------
                                     | Utils |<>--------|Registry|
                                     ---------            ----------
                                      1|    ^1
                                       |    |
                                       |    |
                                       |    |
                                   1..*v    |1
                                      ----------------
           ..........................>|<<interface>> |<...............
           . ........................>|    shape     |               .
           . .                        ----------------               .
           . .                       / \  / \  / \  / \              .
           . .                        -    -    -    -               .
           . .                        |    |    |    |               .
           . .                        |    |    |    |               .
           . .        -----------------    |    |    |               .
           . .        |             --------    |    -----------     .
           . .        |             |           |              |     .
           . .        |             |           |              |     .
           . .        |             |           |              |     .
--------   . .    ----------     ------     ---------      -------   .
|Main  |<>.. ...<>|Toplevel|     |Menu|     |Leaf   |      |Frame|<>..
|Window|          ----------     ------     |Widget |      -------
--------                                    ---------
class diagram (Composite Design Pattern)

shape class act as base to all widget classes. The shape class makes call to utils/library component classes for library/util functions.

2.1.1 Description of components

2.1.1.1 Resource file

A resource file contains specification of GUI layout where widgets are the basic elements of graphics. Widgets are related to each other in parent-child relationship. A parent widget contains child widget which in turn serves as parent to other children. Ex. A TopLevel widget contains menus, frames where as a frame can contain many Leaf widgets like Button, Radio Button, Entries etc. Typically main program calls Toplevel wrapper class's new method passing the resource file name. Toplevel::new parses the resource file and if a Toplevel name is not mentioned then reads the first declared toplevel in the resource file. Typically it would be MainWindow (later it would be changed to have MainWIndow declaration separately). Program can be made to read more than one resource files.

For example, say application.res is a resource file which has following layout.

 Toplevel_MainWindow {
    Menu_1 {
        [
            [
                'cascade',
                '~File',
                -tearoff=>0,
                -menuitems=>
                [
                    [
                        'command',
                        '~exit',
                        -command=>sub{exit}
                    ]
                ]
            ]
        ]
    }
    Frame_1 {
        Button_1 {
            -text => 'OK'
            wm:pack
            -side=>'left'
        }
        Button_2 {
            -text=> 'CANCEL',
            -command=>sub {exit}
        }
        -borderwidth=>2,
        -relief=>'groove'
      }
}

Here a toplevel (Toplevel_MainWindow) contains Menus(Menu_1) and Frame_1 whereas Frame_1 contains Leaf widgets Button_1 and Button_2. Parent-child relationship among widgets in layout will have following look.

Toplevel_MainWindow
          |
          |
-----------
|         |
|         |
Menu_1    Frame_1
          |
          |
          -------------
          |           |
          |           |
          Button_1   Button_2



--------------------------
|                   -[ ]X|
--------------------------
| File                   |
|------------------------|
|[OK] [Cancel]           |
--------------------------
Image console look

Image 1

Now adding a edit box in new child frame to Frame_1, say Frame_1_1 and OK and CANCEL button in Frame_1_2. Say, new addition in is file application1.res. application1.res layout below

Toplevel_MainWindow {
    Menu_1 {
        [
            [
                'cascade',
                '~File',
                -tearoff=>0,
                -menuitems=>
                [
                    [
                        'command',
                        '~exit',
                        -command=>sub{exit}
                    ]
                ]
            ]
        ]
    }
    Frame_1 {
        Frame_1_1 {
            Label {
                -text=>'Enter your name'
                wm:pack
                -side=>'left'
            }
            Entry {
                wm:pack
                -side=>'left'
            }
            -borderwidth=>4,
            -relief=>'groove'
        }
        Frame_1_2 {
            Button_1 {
                -text => 'OK'
                wm:pack
                -side=>'left'
            }
            Button_2 {
                -text=> 'CANCEL',
                -command=>sub{exit}
                wm:pack
                -side=>'left'
            }
            -borderwidth=>4,
            -relief=>'groove'
         }
         -borderwidth=>4,
         -relief=>'groove'
     }
}

New parent-child hierarchy drawn

Toplevel_MainWindow
        |
        |
-----------
|         |
|         |
Menu_1    Frame_1
          |
          |
          --------------
          |            |
          |            |
          Frame_1_1    Frame_1_2
          |            |
          |            |
          -------      ----------
          |     |      |        |
          |     |      |        |
          Label Entry  Button_1 Button_2





  --------------------------
|                   -[ ]X|
--------------------------
| File                   |
|------------------------|
|Enter your name [      ]|
|                        |
|[OK] [Cancel]           |
--------------------------
Image console look

Image 2

A simple single window chat GUI can be drawn like this where all users will share same window space for message display. Clicking on one user button will bring that user relevant messages in the message display window.

Toplevel_MainWindow {
    Frame_1 {
        Frame_1_1 {
            Button_1 {
                -text=>'USER A'
                wm:pack
                -ipadx=>'10',
                -fill=>'x',
                #-expand=>1
            }
            Button_2 {
                -text=>'USER B'
                wm:pack
                -ipadx=>'10',
                -fill=>'x',
                #-expand=>1
            }
            Button_3 {
                -text=>'USER C'
                wm:pack
                -ipadx=>'10',
                -fill=>'x',
                #-expand=>1
            }
            wm:pack
            -side=>'left',
            -fill=>'both',
            -expand=>1
        }
        Frame_1_3 {
            Button_1 {
                -text=>'USER D'
                wm:pack
                -ipadx=>'10',
                -fill=>'x',
            }
            wm:pack
            -side=>'right',
            -fill=>'both',
            -expand=>1
        }
        Frame_1_2 {
            ~Scrolled_1 {
                'ROText',
                -scrollbars=>'se',
                wm:pack
                -fill=>'both',
                -expand=>1
            }
            wm:pack
            -side=>'left',
            -fill=>'both',
            -expand=>1
        }
        wm:pack
        -fill=>'both',
        -expand=>1
    }
    Frame_2 {
        Label {
            -text=>'Type message below'
        }
        Frame_2_1 {
            Entry {
                wm:pack
                -side=>'left',
                -fill=>'both',
                -expand=>1
            }
            Button_2 {
                -text=>'Cancel'
                wm:pack
                -side=>'right'
            }
            Button_1 {
                -text=>'SEND'
                wm:pack
                -side=>'right'
            }
            wm:pack
            -fill=>'both',
            -expand=>1
        }
        wm:pack
        -fill=>'both',
        -expand=>1
    }
}
Toplevel_MainWindow
           |
           |
------------------------------------------
|                                        |
|                                        |
Frame_2                                  Frame_1
|                                        |
|                                        |
----------                               ---------------------
|        |                               |         |         |
|        |                               |         |         |
Label    Frame_2_1                       Frame_1_1 Frame_1_2 Frame_1_3
         |                               |         |         |
         |                               |         |         |
         ----------------                |         ROText    Button_1
         |     |        |                |
         |     |        |                -------------------
         Entry Button_1 Button_2         |        |        |
                                         |        |        |
                                         Button_1 Button_2 Button_3


 ----------------------------------------------------
|                                             -[ ]X|
----------------------------------------------------
| User A  |                             | User D   |
| User B  |                             |          |
| User C  |                             |          |
|         |                             |          |
|         |                             |          |
|         |                             |          |
|         |                             |          |
|         |                             |          |
|         |                             |          |
|         |                             |          |
---------------------------------------------------
|           Type message below                     |
|  ---------------------------------               |
| |                                 |[SEND][Cancel]|
| |                                 |              |
|  ---------------------------------               |
 --------------------------------------------------
Image console look

Image 3

A Single Window Chat GUI

Various sections of a widget in the resource file layout. Every widget declaration has three constituents

  1. widget properties. This is graphical property of the widget, ex. color, size etc... and it would be fed to Perl interpreter as it is. Grammar is same as Perl/Tk. Please refer to Perl/Tk documentation on it.
  2. geometry manager's properties. This is for widget graphics position and layout in parent window. It has syntax of "wm:<geometry manager's name>" followed by properties. Well known geometry manager's are pack, grid, place and form. Please refer to Perl/Tk documentation on this. Again properties are fed to Perl/Tk interpreter as it is.
  3. Miscellaneous function declaration. This is to be called at the time of widget creation. It has the syntax of "MISC:" followed by miscellaneous variable assignments, function declaration and call back declaration(ex. bind for event bindings). All statements made in this section is called immediately after the widget creation . A keyword 'this' signifies current widget instance.

For example,

1       Frame_3_2 {
2           Checkbutton {
3               -text=>"Enable simultanious attack",
4               -variable=>\$IWsimultaniouscheckbutton,
5               -command=>[\&enabledisablewidget,
'$IWsimultaniouscheckbutton',q/getwidget('Toplevel_1.Frame_3.
Frame_3_2.Frame_3_2_1.Entry')/]
6               wm:pack
7               -side=>'left',
8               -anchor=>'center'
9           }
10          Frame_3_2_1 {
11              Entry {
12                  MISC:
13                  disablewidget(this)
14              }
15             
wm:pack
16              -side=>'left'
17          }
18          wm:pack
19          -side=>'left',
20          -fill=>'x',
21          -expand=>1
22          MISC:
23          $DtMenu::IWenablesimultaneousattacks=1;
24      }

In the example above line 3-5 is Checkbutton's widget property, line 7-8 checkbutton's geometry manager's property, line 13 is Miscellaneous function (util sub disablewidget) called after Entry widget created, 'this' keyword for physical widget reference, line 19-21 is widget property for Frame_3_2 and line 23 is Miscellaneous variable assignment just after creation of Frame_3_2 widget.

Other points to be noted are

  • Here pack is the geometry manager used so 'gm:pack' is used as keyword. Various other geometry managers to be used are Grid, Place and Form.
  • Here disablewidget(this); statement will call disablewidget function (a library function) passing the current widget's instance reference. $DtMenu::IWenablesimultaneousattacks=1; will assign value 1 to $DtMenu packages variable Iwenablesimultaneousattacks.

Following diagram illustrates the pack geometry manager's fundamentals.

Filling rectangle, "-fill=>x"
 fill in horizontal direction
 "-fill=>'both' in both dir.
                 \
                  \
                   \
                    \
 ___________________|____________________________________
 |------------------|-----^---------------------------- |  Drawn Window
 ||              ...v.....|..........                  ||      /
 ||              . ---------------- .                  ||     /
 ||          <-----| Drawn Object |---------->         ||    /
 ||              . ---------------- Anchor 'e'         ||<--
 ||              .........|..........                  ||
 ||                       |                            ||
 |------------------------v---------------------------- |
 |                                               ^      |
 |                                               |      |
 |                                               |      |
 |                                               \      |
 |                                                \     |
 |                                                 \    |
 |                                                  ------- 'Top'
 |                                                      |Allocation
 |                                                      |Rectangle
 |                                                      |default
 |                                                      |geometry
 |                                                      |property
 |                                                      |-side=>'lop'
 --------------------------------------------------------

Please refer to Perl/Tk manuals for detail description.  

2.1.1.2 Widget specific files

A widget specific file behave as wrapper class for actual widget and involves in creation till destruction of the widget. i.e. DtToplevel->Toplevel, DtFrame->Frame, DtMenu->Menu etc, If wrapper class for a particular widget is not available then Shape (Base) class's subroutines are called. Typical program flow is, main program calls Toplevel widget wrapper's new subroutine passing the resource file to read. Toplevel class new subroutine creates main window if main window is not created then parse the resource file till first Toplevel layout is found. Code part of Toplevel declaration is passed to Shape::new for recursive operation. Base::new parse the Toplevel widget code and once find widget specific keywords (ex. Menu, Button, Frame etc) then it calls widget specific wrapper's createwidget subroutine to create the physical widget. It then calls new subroutine of the widget just created passing the layout code specific to the widget. Widget wrapper class not handling new subroutine passes this call the Shape::new again and so it is recursive to create child widget belonging to the current widget. This is recursive operation with depth first algorithm.

For Example in resource file declaration

.
   Toplevel_1{
    Menu_1{
         [
             [
                 'cascade',
                 '~File',
                 -tearoff=>0,
                 -menuitems =>
                 [

Main program will call new subroutine of "Toplevel" widget wrapper class and Toplevel wrapper class will call Menu resource wrapper class. In case Menu resource wrapper class is not available then "Shape" Base class functions will be called. This procedure is recursive in nature with depth first algorithm.

Example of DtCheckbutton.pm wrapper on checkbutton widget class

////////////////DtCheckbutton.pm/////////////
1       package DtCheckbutton;
2       use base qw(DtShape);
3       sub createwidget {
4           my ($class,$parentwidget,$widgetclass,$widgetproperty,$wm,$wmdata,$functionlistref)=@_;
5           my $parentwidgetstring;
6           $parentwidget=$parentwidget->$widgetclass(eval $widgetproperty)->$wm(eval $wmdata);
7           $parentwidgetstring='$parentwidget';
8           foreach my $function(@{$functionlistref}) {
9               $function=~s/\bthis\b/$parentwidgetstring/g;
10              eval $function;
11          }
12          return $parentwidget;
13      }
14
15      sub AUTOLOAD {
16          my $program=$AUTOLOAD;
17          $program=~s/^.*:://;
18          eval q/DtCheckbutton->SUPER::/.$program.q/(@_)/;
20      }
21      1;
////////////////DtCheckbutton.pm///////////////

Here, line 2 DtShape is referred as base class. Line 3 defines subroutine to createwidget and Line 15 is for subroutine AUTOLOAD to be called when function is not declared (for MISC functions in resource file). It then transfer the function call to base(SUPER) classes.

--------> Subroutine call
........> Subroutine return

                               ----------
------     ---------------     |Resource|    ------------  -----------
|Main|     |Widget       |     |File    |    |Shape::new|  |Subwidget|
------     |(Ex.Toplevel)|     ----------    ------------  -----------
  |        ---------------         |               |             |
  |               |                |               |             |
  |_<<call new sub routine passing file name as argument>>       |
  ||------------->|                |               |             |
  |-              |                |               |             |
  |               |_ <<Read file for first instance of Widget    |
  |               ||-------------->|               |             |
  |               |- decaration>>  |               |             |
  |               |                |               |             |
  |               |_<<Pass widget code from resource file>>      |
  |               ||------------------------------>|             |
  |               |-               |               |             |
  |               |                |               |             |
  |<<call createwidget sub. for actual widget     _|             |
  |               |<------------------------------||             |
  |               |  creation>>    |              -|             |
  |               |                |               |             |
  |               |_ <<returns widget reference, now it will be  |
  |               ||.............................->|             |
  |               |- parent for any subwidget declared in resour.|
  |               |                |               |             |
  |               |                |               |  (1)        |
<<calls new sub. for all subwidgets found for the parent widget>>|
  |               |                |               |_            |
  |               |                |               ||----------->|
  |               |                |               |-            |
  |               |                |               |             |
  |               |    <<call delegated to Base class new sub>> _|
  |               |                |               |<-----------||
  |               |                |               |            -|
  |               |                |               |             |
           <<call createwidget sub. to create the actual widget>>|
  |               |                |               |_            |
  |               |                |               ||----------->|
  |               |                |               |-            |
  |               |                |               |             |
  |<<return widget ref., now it will be parent to any subwidget _|
  |               |                |               |<...........||
  |               |                 declared in resource file>> -|
  |               |                |               |             |
  |<<repeat from step (1) for other subwidgets of _|             |
  |               |<..............................||             |
  |of the current widget. Depth first recursive>> -|             |
  |               |                |               |             |
  |  <<return>>  _|                |               |             |
  |<.............||                |               |             |
  |              -|                |               |             |
Sequence diagram of call flow

2.1.1.3 Miscellaneous files

A miscellaneous file keeps miscellaneous(library) subroutines to be configured-in/called through other modules, ex. Resource files, wrapper widget classes and main program. One of the important property of miscellaneous files is to keep frame work related information in registry. Mainwindow, Toplevel window resource name and other global information are kept in the registry.

Export header for DtUtils package(one of miscellaneous package).

//////////////////DtUtils.pm////////////////
package DtUtils;
BEGIN {
   use Exporter ();
   our (@ISA,@EXPORT,@EXPORT_OK,%EXPORT_TAGS);
   @ISA=qw(Exporter);
   @EXPORT=qw(enabledisablewidget disablewidget addattacks
      deleteattacks detachconsole attachconsole mainwindow
       toplevelwidgetname getwidget);
   @EXPORT_OK=();
   %EXPORT_TAGS=();
  }
our @EXPORT_OK;
.
.
////////////////DtUtils.pm/////////////////

enablewidget and disablewidget subroutines in DtUtils.pm

////////////////DtUtils.pm///////////////
   sub disablewidget {
       my $class=shift;
       my $widget=$class;
       $widget=shift if @_;
       my $changecolor=shift if @_;
       my @bindtags;
       if(ref $widget) {
           $widget->configure(-background=>'#BBBBBB') if !defined $changecolor;
           @bindtags=$widget->bindtags;
           if ($bindtags[0]=~/^Tk::/) {
               $widget->bindtags([@bindtags[1,0,2,3]]);
               $widget->bind('<Button>'=>sub{$_[0]->break});
               $widget->bind('<Key>'=>sub{$_[0]->break});
           }
       }
   }
   sub enablewidget {
       my $class=shift;
       my $widget=$class;
       $widget=shift if @_;
       my $changecolor=shift if @_;
       my @bindtags;
       if(ref $widget) {
        $widget->configure(-background=>'grey') if !defined $changecolor;
        @bindtags=$widget->bindtags;
        if ($bindtags[0]!~/^Tk::/) {
            $widget->bindtags([@bindtags[1,0,2,3]]);
            $widget->bind('<Button-1>'=>undef);
        }
       }
   }
 ////////////////////DtUtils.pm///////////////

2.1.1.4 Main program

Main program is bootstrap file which is responsible to make widget wrappers to read the resource file and start create the physical widgets and build event maps for various events accordingly. It then enter to event MainLoop. Typically main program calls Toplevel::new method passing the resource file name as argument to it (i.e. DtTopLevel->new(dtplgui.res). With no argument resource file with same name as main program will be taked as default. Here it will be dtplgui.res as main program name is dtplgui.pl. Starting with DtTopLevel package new method when Toplevel is not specified it will pick first Toplevel declaration in the resource file. Typically it would be declaration for the main window.  

/////////application.pl, main program.//////////
1   #!/usr/bin/perl -w
2   use Tk;
3   use Tk::ROText;
4   use lib "../Lib";
5   use DtToplevel;
6   use DtMenu;
7   use DtButton;
8   use DtScrolled;
9   use DtCheckbutton;

10  if (@ARGV) {
11    $mw=DtToplevel->new($ARGV[0]);
12  } else {
13      $mw=DtToplevel->new('application.res');
14  }
15  $mw->title("Application");
16  my $iconptr=$mw->Photo(-file=>'image.GIF',-format=>'GIF',-width=>'32',-height=>'32');
17  $mw->iconimage($iconptr);
18  MainLoop;
//////////application.pl//////////////////////

2.2 Program execution

There are two ways resource file can be read and GUI can be brought. In first way, resource file name can be passed as command line argument (one file at a time).  

Example

application.pl application.res

Another way is to call DtTopLevel::new method and pass the resource file name. It also except Toplevel name that has to be read from resource file and then to be generated.

Example

DtTopLevel->new('application1.res');
DtTopLevel->new($wm,'Toplevel_2');

Here $wm is already created main window reference.

2.3 Target Directory Structure

Source code is distributed in a directory GUIGeneric. It has two subdirectories Application and LIB. Application contains application specific files (button.pm application.pl, application.res etc) where LIB contains various library files which include utility modules and some widget modules/wrappers (DtCheckbutton.pm, DtMenu.pm, DtScrolled.pm, DtShape.pm, DtToplevel.pm, DtUtils.pm and DtRegistry.pm).

GUIGeneric(DIR)
   |
   |
   +------------------+
   |                  |
   |                  |
   Application(DIR)   LIB(DIR)
   |                  |
   |                  |
   application.pl     DtCheckbutton.pm
   application.res    DtMenu.pm
                      DtScrolled.pm
                      DtShape.pm
                      DtToplevel.pm
                      DtUtils.pm
                      DtRegistry.pm

LIB directory can be linked to Application with either setting PERL5LIB environment variable to LIB directory or using "use lib" declaration in the Perl script itself.

Example

In the application.pl line 4(see last program) is 'use lib "../Lib"'.

If related GUI interfaces need to be generated then the directory structure can be devised to accommodate various command line execution lines. Something like an application can have many services through different interfaces. Each interface supports one set of command line options/services. So this way an application can have multiple set of command line execution options. Even application can be executed from a script (e.g. Shell) or a set of scripts where each script my execute one set of command line options/interface or multiple set of command line options/interfaces. Or there can be many applications each supporting various interfaces (set of command line options) and many scripts(ex shell) may execute application interfaces through intermediate scripts. In directory arrangement, if an application supports many interfaces then interface specific directory will contain the interface specific files. Like main Perl file, resource file, any custom widget wrapper file. For example, if one need to write one more GUI application, Application1, then he need to create one more directory, Application1 and link the libraries to LIB.

GUIGeneric(DIR)  /------------ New Directory
         |      /
         |     |
         ------|--+-----------------------------+
         |     |             |                  |
         |     v             |                  |
         Application1(DIR)   Application(DIR)   LIB(DIR)
         |                   |                  |
         |                   |                  |
         application1.pl     .                  DtCheckbutton.pm
         application1.res    .                  DtMenu.pm
                                                DtScrolled.pm
                                                DtShape.pm
                                                DtToplevel.pm
                                                DtUtils.pm

2.3.1 Application with Interfaces

+-------+
|       |----------O
+-------+
Single interface application
+-------+
|       |----------O
|       |.
|       |.
|       |----------O
+-------+
Multiple interface application
+-------+
|       |----------O
+-------+
+-------+
|       |----------O
|       |----------O
+-------+
  .
  .
+-------+
|       |----------O
|       |.
|       |.
|       |----------O
+-------+
Set of interfaces with various types
+-------+                         ----------
|       |----------O<-------------|        |
+-------+                   |---//| Script |
+-------+                   |   / |        |
|       |----------O<--------  /  ----------
|       |----------o           |
+-------+                      |
  .                            |
  .                            |
+-------+                      |
|       |----------o           |
|       |.                    /
|       |.                   /
|       |----------O<-------/
+-------+
Application interfaces called through a script
              .-----
+-------+     v    |         ----------
|       |-----O    ----------|Script11|<-\
+-------+     ^             /----------   |
              |            /              |
              ------\     /               |
+-------+            \   /                |
|       |-----O<------\--                 \ ---------+
|       |-----O<-      \     ----------   _\|Script21|<--
+-------+               -----|Script12|<-/  ---------+   \
  .               \         /|        |<-      .          \ +---------
  .                \       / ----------  \     .           \|ScriptN1|
+-------+           \     /     .         \    .           /----------
|       |-----O<-----\---/   ----------    \----------    /
|       |.            -------|Script1N|<----|Script22|<--/
|       |.                  /----------     ----------
|       |-----O<-----------/
+-------+
Scripts called through other scripts

Through scripts calling others and then in more degree may lead to development of graphical utility can list other graphical utility and so on

Example.

Script calling script (degree 2)

_______________________________________________
|                Script21                     |
-----------------------------------------------
|File                                     Help|
|---------------------------------------------|
|                                             |
|  ___________    ___________    ___________  |
|  |         |    |         |    |         |  |
|  |Script11 |    |Script12 |    |Script13 |  |
|  |         |    |         |    |         |  |
|  -----------    -----------    -----------  |
|                                             |
|  ___________    ___________                 |
|  |         |    |         |                 |
|  |Script14 |    |Script1N |                 |
|  |         |    |         |                 |
|  -----------    -----------                 |
|                                             |
|                                             |
|---------------------------------------------|


_______________________________________________
|                Script11                     |
-----------------------------------------------
|File                                     Help|
|---------------------------------------------|
|               |                             |
|               |           ..                |
|               |       .    |   .            |
|               |     .      |     .          |
|               |    .       |      .         |
|               |    .       |-------         |
|               |     .      |     .          |
|               |       .    |   .            |
|               |           ..                |
|               |                             |
|               |                  |--|       |
|               |               |--|  |       |
|               |            |--|  |  |       |
|               |         |--|  |  |  |       |
|               |       --|  |  |  |  |       |
|               |    --|  |  |  |  |  |       |
|               |   |__|__|__|__|__|__|       |
|               |                             |
|---------------------------------------------|

3. EXAMPLE (SECTION) DataPool Graphical User Interface Construction

3.1 About Tool

Datapool (http://packetstormsecurity.org/DoS/) is a tool used to test various telecom / network products against vulnerability to potential DoS (Denial of Service) attacks. A current datapool(3.3) software version is command-line utility for Linux users. Various options provided by Command Line utility are

"Usage: $0 [-i] [source ip] [-v] [logfile] [-p] [portlow-porthigh] "
"[-s] [-l] [T1|T3|OC3|Modem|Slowass] [-x] [-k] [-a] [-t] [# of attacks]"
"[-r] [attackname]"
"Options:"
"[-p]: Specifies port range to scan.  ex: -p 1-1024"
"[-x]: "Don't stop till they drop"
"[-v]: Logs results of scan to file.  ex: -v logfile.log"
"[-s]: Scan ports only."
"[-l]: Specifies line speed.  Choose from T1,T3, and Modem."
"[-i]: Specifies source IP.  ex: -i 127.0.0.1"
"[-k]: Wait till host is online, then attack."
"[-a]: Loop attack. (Used with -k and -x can keep a connection dropped.)"
"[-t]: Number of simultaneous attacks to launch. ex: -t 4"
"[-r]: Run this attack only. ex: -r onetwothreefour"

3.2 About GUI

This tool is a possible Graphical User Interface to Datapool Command Line Application. GUI is written in Perl/Tk in order to make it portable on both Unix/Linux and Windows flavors.

3.2.1 Main Window of tool proposed look and feel

Image 4

3.2.1.1 Frame hierarchy and elements description

Image 5

3.2.1.2 Menu Look

Image 6

3.2.1.3 Detached console look

Image 7

3.3 Target directory structure

Source code is distributed among three directories DataPool, IO and LIB. datapoolgui.sh and README are located in current/main directory. DataPool contains datapool specific files (button.pm dtplgui.pl, dtplgui.res etc) where LIB contains various library files which include utility modules and some widget modules/wrappers (DtCheckbutton.pm, DtMenu.pm, DtScrolled.pm, DtShape.pm, DtToplevel.pm, DtUtils.pm and DtRegistry.pm). IO contains Perl CPAN module (IO-Tty-1.08.tar.gz) for creating line buffer terminals so that writing to pseudo terminals is line buffered and output in console window would be faster.

Image 8

3.4 Tool Installation

Tool Installation(Red Hat Linux): Tool is provided in zip file. It can be unzipped in any directory and that directory need to be added to PATH environment of the shell. Untar IO/Pty/IO-Tty-1.08.tar and run installation script as follows (in order to install pseudo terminal), also refer to README file provided.

perl Makefile.PL
make
make test
make install

Rest of the tool installation steps are provided in README file provided with the software. Here is the snapshot
If Perl-Tk and datapool command line package is not installed, DataPoolGUI would not work.
Perl-Tk is typically available in the OS DVD.
Perl-Tk is also downloadable from the corresponding OS site. datapool can also be downloaded from internet.
This DataPoolGUI version 1.0.0 is written for datapool3.3.

To work correctly with datapool3.3 command line version, please edit <Installation directory>/DataPoolGUI/DataPool/datapool.sh in order to locate the datapool3.3 shell script datapool.sh.

Type datapoolgui.sh to start the GUI version.

Windows TRIAL

It can be tried if DataPool is available for Windows. Perl interpreter can be downloaded from www.activestate.com if it is not available on Windows machine. Unzip the zip file in some directory.

Here Pty (pseudo terminal) would not work as Windows does not support. In order to try out GUI look and feel execute dtplgui.pl without any command line argument.

>>>dtplgui.pl

3.5 GUI Snapshots

3.5.1 Main Window LINUX

Image 9

Main Window on WINDOWS

Image 10

3.5.2 Console dissociation in a new Window

Image 11

Image 12

3.5.3 Optionals removal from Main Window

Image 13

Image 14

Image 15

3.5.4 Opening File to read

Image 16

4. Summary

Datapool GUI is developed through composite structural design pattern where someone can generate GUI while following some set of rules. Here in, User Interface for security tool Datapool, an user can have all possible options what command line user interface for the tool provides. Perl/Tk implementation provides the feasibility of porting it on various Operating systems where Perl/Tk and Datapool is available. Future version of the GUI will contain options for firing parallel/multiple attacks simultaneously with each attack running in separate consoles.

5. References

Mastering Perl/Tk, Steve Lidie and Nancy Walsh.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)