The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Проблемы с raw sockets под FreeBSD 5.1"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Проблемы с raw sockets под FreeBSD 5.1"
Сообщение от Tsr Искать по авторуВ закладки on 07-Апр-04, 15:16  (MSK)
Доброе время суток!
Не подскажет ли всезнающий олл, как разобраться с сабжем:

при работе с raw socket если во фрагменте:
<cut>
sockd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);

char on = 1;
setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));

<cut>
переменная on != 0
при вызове sendto выдается ошибка "неверный аргумент", хотя sockd открылся нормально.
иначе формируется пакет с IP-заголовком, отличным от моего.
Как побороть сие безобразие.

С уважением, Андрей.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "Проблемы с raw sockets под FreeBSD 5.1"
Сообщение от 3bepb Искать по авторуВ закладки on 08-Апр-04, 08:56  (MSK)
У меня тоже такая проблема была. Я сильно не разбирался но если правильно составить ip заголовок то всё должно заработать видимо ядро его проверяет.
Для примера:
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in_systm.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

#define PORT 40

int send_packet(int sock_, struct sockaddr_in sin_, char *buff_);
u_short checksum(u_short *addr, int len);

int main(int argc, char *argv[])
{
  int i, sock, on = 1;
  struct sockaddr_in sin;
  struct _pseudoheader {
    struct in_addr src_addr;
    struct in_addr dst_addr;
    u_char zero;
    u_char protocol;
    u_char length;
  } pseudoheader;
  struct in_addr src, dst;
  struct ip *iph;
  struct tcphdr *tcp;
  u_char *buf = (char *)malloc(sizeof(struct ip) + sizeof(struct tcphdr));
  u_char *pseudo = (char *)malloc(sizeof(struct _pseudoheader) +
  sizeof(struct tcphdr));

  if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
    printf("socket\n");
    exit(1);
  }

  if (setsockopt(sock, 0, 2, &on, sizeof(on)) < 0) {
    printf("setsockopt\n");
    exit(1);
  }
  
  iph = (struct ip *)buf;
  tcp = (struct tcphdr *)(buf + sizeof(struct ip));

  inet_aton("10.16.17.23",&src);
  inet_aton("10.16.17.1",&dst);

  pseudoheader.src_addr = src;
  pseudoheader.dst_addr = dst;
  pseudoheader.zero = 0;
  pseudoheader.protocol = IPPROTO_TCP;
  pseudoheader.length = htons(sizeof(struct tcphdr));

  memcpy(pseudo,&pseudoheader,sizeof(struct _pseudoheader));
  memcpy(pseudo + sizeof(struct _pseudoheader),buf + sizeof(struct ip),
sizeof(struct tcphdr));

  iph->ip_hl = 5;
  iph->ip_v  = 4;
  iph->ip_tos = 0;
  iph->ip_len = ntohs(sizeof(struct ip) + sizeof(struct tcphdr));
  iph->ip_id  = rand();
  iph->ip_off = htons(IP_DF);
  iph->ip_ttl = 64;
  iph->ip_p = IPPROTO_TCP;
  iph->ip_sum = 0;
  iph->ip_src = src;
  iph->ip_dst = dst;
  
  tcp->th_sport = htons(rand());
  tcp->th_dport = htons(PORT);
  tcp->th_seq   = ntohl(rand());
  tcp->th_ack   = rand();
  tcp->th_off   = 5;
  tcp->th_flags = TH_SYN;
  tcp->th_win   = htons(512);
  tcp->th_sum   = checksum((u_short *)pseudo,sizeof(struct _pseudoheader) +
sizeof(struct tcphdr));
  tcp->th_urp   = 0;

  sin.sin_family = AF_INET;
  sin.sin_port = htons(PORT);
  sin.sin_addr = dst;

  send_packet(sock,sin,buf);

  free(buf);  
  free(pseudo);
  return 0;
}

int send_packet(int sock_, struct sockaddr_in sin_, char *buff_)
{
  int err;

  if((err = sendto(sock_, buff_, (size_t)(sizeof(struct ip) +
sizeof(struct tcphdr)), 0, (struct sockaddr *)&sin_, sizeof(sin_))) < 0) {
    printf("sendto %d\n",err);
  }
  
  printf("packet send...\n");

  return err;
}

u_short checksum(u_short *addr, int len)
{
  u_short *w = addr;
  int i = len;
  int sum = 0;
  u_short answer;
  
  while(i > 0) {
    sum += *w++;
    i -= 2;
  }
  if(i == 1) sum += *(u_char *)w;
  sum = (sum >> 16) + (sum & 0xffff);
  sum = sum + (sum >> 16);
  
  return (~sum);  
}
  
Код я писал в OpenBSD.

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Спонсоры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2022 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру