Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.03.2011, 19:30   #1
Silver_Swift
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 17
По умолчанию Не создается RAW-socket.

Сидя под убунтой пытаюсь создать raw-socket:

#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int fd= socket(AF_INET, SOCK_RAW,IPPROTO_ICMP);
qDebug()<<fd;
}

Все компилится, однако ж socket возвращает -1 при выполнении программы. Кто знает почему?
Silver_Swift вне форума Ответить с цитированием
Старый 17.03.2011, 21:22   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

а права какие? под кем запускаете?
p51x вне форума Ответить с цитированием
Старый 18.03.2011, 00:29   #3
Silver_Swift
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 17
По умолчанию

Упс... Обычным пользователем. С sudo заработало.

Тогда странный вопрос. Надо будет всегда запускать прогу от супервизора или можно в коде что-то прописать?
Silver_Swift вне форума Ответить с цитированием
Старый 21.03.2011, 21:49   #4
Silver_Swift
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 17
По умолчанию

Следующий вопрос серьезней.
Нужно сгенерировать icmp-пакет и отправить его в сеть. Делаем это пять же под linux. Используем структуры ip и icmphdr. Однако программа работать как надо не желает. Ошибок не выдает. Почему ж так?
Код:
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int main(int argc, char **argv) 
{
int sockfd, n;
char *sendline,datagram[4096];
cout<<datagram<<endl;
struct sockaddr_in servaddr;
struct ip *iphead = (struct ip*)datagram;
struct icmphdr *icphead = (struct icmphdr*)datagram+sizeof(struct ip);
iphead->ip_hl = 5;
iphead->ip_v=4;
iphead->ip_tos=0;
iphead->ip_len=sizeof(struct ip)+sizeof(struct icmphdr);
iphead->ip_id=htonl(54321);
iphead->ip_off=0;
iphead->ip_ttl=255;
iphead->ip_p=6;
iphead->ip_sum=0;
iphead->ip_src.s_addr=servaddr.sin_addr.s_addr;
iphead->ip_dst.s_addr=servaddr.sin_addr.s_addr;
icphead->type=0;
icphead->code=0;
icphead->checksum=0;
iphead->ip_sum=iphead->ip_len;

servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(17000);
servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sockfd=socket(PF_INET, SOCK_RAW,IPPROTO_ICMP);

{
int one=1;
const int* val=&one;
if (setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one))<0)
printf("sockopt");
}
cout<<datagram<<endl;
write(1,"Enter string\n", 13);
sendline = (char*)datagram+sizeof(struct ip)+sizeof(struct icmphdr);
n=read(0, sendline, 100);

int m=sendto(sockfd, sendline, n+sizeof(struct ip)+sizeof(struct icmphdr), 0, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in));
printf("отправлено %d\n",m);
cout<<datagram<<endl;
close(sockfd);
return 0;
}
Осознав что делаю:
Не знаю как правильно запихнуть заголовки и информацию в сокет. Косяк в этом. Как правильно кинуть в char* две структуры и данные?

Последний раз редактировалось Silver_Swift; 21.03.2011 в 21:59.
Silver_Swift вне форума Ответить с цитированием
Старый 23.03.2011, 01:08   #5
Silver_Swift
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 17
По умолчанию

Однако одиноко как-то мне тут... Но предпримем еще одну попытку обращения к сообществу.
С отправкой разобрался все работает. Теперь затык в том, чтобы принимать пакеты на другой машине.
Программа:
Код:
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <unistd.h>
#include <arpa/inet.h>
int main() {
int sockfd, n;

char mesg[8092];
struct sockaddr_in ADR;

sockfd=socket(PF_INET, SOCK_RAW,IPPROTO_TCP);
if (bind(sockfd,(struct sockaddr*)&ADR,sizeof(ADR))==-1)
printf("bind\n");
printf("starts...\n");
	recv(sockfd,mesg,8092,0);
        printf("REQUEST %s \n", mesg);
return 0;}
Ловит UDP и TCP пакеты на ура. А ICMP не видит совсем. Кто-нибудь может подсказать как правильно сделать сокет с которого можно считывать ICMP пакеты?
Silver_Swift вне форума Ответить с цитированием
Старый 23.03.2011, 04:29   #6
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

может поставить IPPROTO_ICMP вместо IPPROTO_TCP?
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 23.03.2011, 07:38   #7
Silver_Swift
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 17
По умолчанию

Само собой. Так и было, TCP остался после экспериментов. Дело не в этом пакеты все равно не идут.

Может ось какие-то пакеты отфильтровывает и надо какую-то опцию включить?

edited: И кстати со строкой sockfd=socket(PF_INET, SOCK_RAW,IPPROTO_TCP); программа нормально ловит ICMP пакеты и читает IP заголовок, а дальше косячит.

Почему?

Последний раз редактировалось Silver_Swift; 23.03.2011 в 08:16.
Silver_Swift вне форума Ответить с цитированием
Старый 23.03.2011, 11:40   #8
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> Ловит UDP и TCP пакеты на ура. А ICMP не видит совсем.

> программа нормально ловит ICMP пакеты и читает IP заголовок

как-то одно другому слегка противоречит, не?
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 23.03.2011, 17:11   #9
Silver_Swift
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 17
По умолчанию

Мде... Все описал, код приложил, а конструктива нуль...

Если при создании сокета выбрать протокол ICMP, то сообщения не будут читаться. Если выбрать протокол TCP то программа будет читать пакеты, при чем любые в том числе ICMP. При этом ICMP заголовок и информация искажаются, а IP заголовок читается нормально. Мне казалось извлечение этой мысли из моих постов не должно представлять трудностей.

Есть чего по делу сказать?

edited: А TCP-пакеты с "собранным вручную" IP заголовком принимаются вообще без проблем...

Последний раз редактировалось Silver_Swift; 23.03.2011 в 17:14.
Silver_Swift вне форума Ответить с цитированием
Старый 23.03.2011, 22:02   #10
Silver_Swift
Пользователь
 
Регистрация: 10.12.2010
Сообщений: 17
По умолчанию

Ошибку нашел, все работает, тему можно закрывать.
veniside спасибо за приятную компанию.
Silver_Swift вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
TBitmap -> RAW Celestia Мультимедиа в Delphi 5 17.01.2011 18:59
Raw Socket C++ GanBit Помощь студентам 0 21.09.2010 10:01
Тонкости программирования RAW SOCKET под Linux seryoga89 Общие вопросы C/C++ 0 13.06.2010 16:44
Raw сокеты liljon Win Api 1 21.05.2010 23:45
не создается socket() isPolin C/C++ Сетевое программирование 2 24.06.2009 14:41