/*
    ettercap -- dissector Yahoo Messenger -- TCP 5050

    Copyright (C) 2001  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.

    $Id: ec_dissector_ymsg.c,v 1.3 2002/04/19 11:10:40 alor Exp $
*/

#include "include/ec_main.h"

#include "include/ec_dissector.h"
#include "include/ec_decodedata.h"
#include "include/ec_inet_structures.h"

// protos

FUNC_DISSECTOR(Dissector_ymsg);

// --------------------

FUNC_DISSECTOR(Dissector_ymsg)
{

   TCP_header *tcp;
   u_char *payload;
   u_char collector[MAX_DATA];
   DATA_DISSECTOR;

   tcp = (TCP_header *) data;

   if (data_to_ettercap->datalen == 0) return 0;      // no data...

   payload = (char *)((int)tcp + tcp->doff * 4);

   memset(collector, 0, MAX_DATA);
   memcpy(collector, payload, data_to_ettercap->datalen);

   if (memcmp(collector, "YMSG", 4)) return 0; /* not a yahoo messenger packet */
   
   if (Conn_Mode) {
   
      sprintf(data_to_ettercap->type, "Yahoo MSG");
      
      if ( ntohs(tcp->dest) == SERV_PORT)  {
         u_char *p, *q, *end;
     
         end = collector + data_to_ettercap->datalen;
         
         p = strstr(collector, "\xC0\x80");  /* standard ymesg separator */
         if (!p) return 0;
         
         if (*(p-1) != 0x30)  return 0;  /* login is ASCII 0 */
         
         DEBUG_MSG("YMSG Logins");
         
         p = p + 2; /* skip the separator */
         for (q=p; *q != 0xc0 && q <= end; q++);
         if (q == end) return 0;
         *q = 0;  /* replace the separator with a NULL terminating string */
         
         snprintf(data_to_ettercap->user, sizeof(data_to_ettercap->user), "%s\n", p);
         data_to_ettercap->user[sizeof(data_to_ettercap->user)-2] = '\n';
         data_to_ettercap->user[sizeof(data_to_ettercap->user)-1] = '\0';
         
         DEBUG_MSG("YMSG username");
        
         p = q + 2; /* skip the separator */
         if (*p != 0x36)  return 0;  /* login is ASCII 6 */
         p = p + 3; /* skip the separator and the "6" */
         for (q=p; *q != 0xc0 && q <= end; q++);
         if (q == end) return 0;
         *q = 0;  /* replace the separator with a NULL terminating string */
           
         snprintf(data_to_ettercap->pass, sizeof(data_to_ettercap->pass), "%s\n", p);
         data_to_ettercap->pass[sizeof(data_to_ettercap->pass)-2] = '\n';
         data_to_ettercap->pass[sizeof(data_to_ettercap->pass)-1] = '\0';
         
         DEBUG_MSG("YMSG password");
         
         sprintf(data_to_ettercap->info, "The pass is in MD5 format ( _2s43d5f is the salt )");
         
         return 0; 
      }
   } else { /* data dissector */
  
      u_char *p, *q, *end;
      char *from, *to, *message;
   
      end = collector + data_to_ettercap->datalen;
      
      p = strstr(collector, "\xC0\x80");  /* standard ymesg separator */
      if (!p) return 0;
      
      if (*(p-1) != 0x31)  return 0;  /* message is ASCII 1 */
      
      DEBUG_MSG("YMSG private message");
      
      p = p + 2; /* skip the separator */
      for (q=p; *q != 0xc0 && q <= end; q++);
      
      if (q == end) return 0;
      
      *q = 0;  /* replace the separator with a NULL terminating string */
      from = strdup(p);  /* get the sender */
      
      p = q + 5; /* skip the two separators and the ASCII 5 */
      for (q=p; *q != 0xc0 && q <= end; q++);
      
      if (q == end) {
         free(from);
         return 0;
      }
      
      *q = 0;  /* replace the separator with a NULL terminating string */
      to = strdup(p);  /* get the receiver */
      
      p = q + 6; /* skip the two separators and the ASCII 14 */
      for (q=p; *q != 0xc0 && q <= end; q++);
      
      if (q == end) {
         free(from);
         free(to);
         return 0;
      }
      
      *q = 0;  /* replace the separator with a NULL terminating string */
      message = strdup(p);  /* get the receiver */
      
      memset(sniff_data_to_ettercap->data, 0, sizeof(sniff_data_to_ettercap->data));
      sprintf(sniff_data_to_ettercap->data, "*** YAHOO MESSAGE ***\n From: %s\n To: %s\n\n Message: %s\n\n", from, to, message);
      
      sniff_data_to_ettercap->datasize = strlen(sniff_data_to_ettercap->data);
      
      free(from);
      free(to);
      free(message);
   }
   
   return 0;
}

/* EOF */

// vim:ts=3:expandtab

