Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сырые сокеты. Ошибка с адресами входящими и исходящими

1.9K
26 июня 2008 года
WWTLF
35 / / 16.06.2003
Есть такой снифер, сделан на основе примере статьи на этом сайте. Проблема в том что он неправильно определяет входящие и исходящие адреса. Когда я обращаюсь с машины на которой он запущен на другую машину например с командой telnet 192.168.0.3 144 то он источником указывает не себя а как раз 192.168.0.3, а если наобарот с той машины то как раз верно источник ...0.3 получатель тот на котором запущен. Может у меня что не так с объявленеим и заполнением IP заголовка?
Код:
/*
 * File:   main.cpp
 * Author: root
 *
 * Created on 25 Июнь 2008 г., 18:28
 */
#include <stdio.h>
#include <string.h>
#include <errno.h>  
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>  
//#include <linux/in.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <memory.h>
#include        <sys/fcntl.h>
#include <stdlib.h>

typedef struct IPHeader {
  u_char   iph_verlen;   // версия и длина заголовка
  u_char   iph_tos;      // тип сервиса
  u_short  iph_length;   // длина всего пакета
  u_short  iph_id;       // Идентификация
  u_short  iph_offset;   // флаги и смещения
  u_char   iph_ttl;      // время жизни пакета
  u_char   iph_protocol; // протокол
  u_short  iph_xsum;     // контрольная сумма
  u_long   iph_src;      // IP-адрес отправителя
  u_long   iph_dest;     // IP-адрес назначения
} IPHeader;

struct UdpHeader
{
    u_short src_port;
    u_short targ_port;
    u_short length;
    u_short checksum;
};


int main(int argc, char **argv) {
  int sock, n;
  int ret;
    unsigned char buffer[65536];
  unsigned char  *ethhead;
  struct ifreq ethreq;
  IPHeader IPh;
  UdpHeader UDPh;
  sockaddr_in temp1,temp2;
 
 
  if ( (sock=socket(PF_PACKET, SOCK_RAW,
                    htons(ETH_P_IP)))<0) {
    perror("socket");
    exit(1);
  }

  /* Set the network card in promiscuos mode */
  strncpy(ethreq.ifr_name,"eth1",IFNAMSIZ);
  if (ioctl(sock,SIOCGIFFLAGS,&ethreq)==-1) {
    perror("ioctl");
    close(sock);
    exit(1);
  }
  ethreq.ifr_flags|=IFF_PROMISC;
  if (ioctl(sock,SIOCSIFFLAGS,&ethreq)==-1) {
    perror("ioctl");
    close(sock);
    exit(1);
  }
 
  /* set socket to nonblock */
    ret = fcntl(sock, F_GETFL);
    ret |= O_NONBLOCK;
    if ( fcntl(sock, F_SETFL, ret) < 0 ) {
        printf("set socket to nonblock fail [%d] !\n", errno);
        //goto exit_program;
    }

 
 
  while (1) {
      memset(&IPh-14,0,sizeof(IPHeader)+14);
    n = recvfrom(sock,buffer,2048,0,NULL,NULL);
    if (n>42) {
        printf("----------\n");
        printf("%d bytes read\n",n);
        ethhead = buffer;
        printf("Source MAC address: "
           "%02x:%02x:%02x:%02x:%02x:%02x\n",
           ethhead[0],ethhead[1],ethhead[2],
           ethhead[3],ethhead[4],ethhead[5]);
        printf("Destination MAC address: "
           "%02x:%02x:%02x:%02x:%02x:%02x\n",
           ethhead[6],ethhead[7],ethhead[8],
           ethhead[9],ethhead[10],ethhead[11]);
        memcpy(&IPh,buffer+14,sizeof(IPHeader));
        memcpy(&UDPh,buffer+14+sizeof(IPHeader),sizeof(UdpHeader));
   
        memcpy(&temp1.sin_addr.s_addr, &IPh.iph_src,sizeof(in_addr));
        memcpy(&temp2.sin_addr.s_addr , &IPh.iph_dest,sizeof(in_addr));
        printf("Source IP: %s:%d\n",inet_ntoa(temp1.sin_addr),htons(UDPh.src_port));
        printf("Dest   IP: %s:%d\n",inet_ntoa(temp2.sin_addr),htons(UDPh.targ_port));
        switch (IPh.iph_protocol){
            case IPPROTO_TCP:
               printf("Protool  IPPROTO_TCP\n");    
            break;
            case IPPROTO_UDP:
               printf("Protool  IPPROTO_UDP\n");    
            break;
            case IPPROTO_ICMP:
               printf("Protool  IPPROTO_ICMP\n");    
            break;  
            default:
               printf("Protool %d \n",IPh.iph_protocol);
            break;
        }
    }
  }
   
    return (EXIT_SUCCESS);
}


И еще у меня две сетевухи, как мне перехватиывать только на одной сетевухе? читал в статье про роу сокеты, что если я буду использовать bind тогда я не смогу перехватывать пакеты которые адресованы не мне...
502
27 июня 2008 года
Jail
550 / / 30.01.2007
Я надеюсь Вы сами понимаете свой код? Ели нет, то и разговаривать то собственно неочем)))
Какой компилятор используете? g++? Вижу в комменте у Вас @main.cpp@, а директивы extern C { ...} где? Вы используете в данном случае "чистый" Си, а в С++ есть классы они позволяют удобно инкапсулировать все то, что Вы вынесли во внешние функции. http://www.proklondike.com/contentview.php?content=471
[QUOTE=WWTLF]И еще у меня две сетевухи, как мне перехватиывать только на одной сетевухе?[/QUOTE]
Libpcap в помощь -> http://sourceforge.net/projects/libpcap/
Более профессиональный подход будет заключаться в использовании библиотеки libpcap, а не мучаться с RAW сокетами. Парадигма проста - для сетевого снифера используем libpcap (тогда уровень фильтрации повыситься до солидного), для соединения с хостами в сети все же лучше будет использование протокола RPC.
1.9K
27 июня 2008 года
WWTLF
35 / / 16.06.2003
Спасибо за книгу...
1.9K
29 июня 2008 года
WWTLF
35 / / 16.06.2003
С проблемой источника и приемника разобрался, ethernet заголовк неверный у меня в коде. Правильный: ПРИЕМНИК ИСТОЧНИК ПРОТОКОЛ. У меня же следуюя обычной человеческой логие сначало источник потом приемник.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог