Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.138.69.45] |
|
Сообщ.
#1
,
|
|
|
Доброго всем времени суток!
Есть программа-клиент, отправляющая мне с удалённого компа UDP сообщения, и есть программа-сервер на моём компе, которая должна их ловить. Если верить снифферу, то пакеты успешно до меня доходят, отправителю тут же возвращают ICMP Destination unreachable (Host administratively prohibited), но программа-сервер ничего не получает. Когда я тестировал ту же программу на локальном хосте (и сервер и клиент), всё работало. В чём может быть дело? Может кто-то сталкивался или просто догадывается? Код программы-клиента: #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string> #include "string.h" using namespace std; int main(int argc, char** argv) { int m_sock; // дескриптор сокета sockaddr_in m_addr; // переменная адреса интерфейса sockaddr_in s_addr; // переменная адреса получателя string my_addr = "192.168.0.211";// Адрес локального интерфейса string ip_addr = "192.168.0.90";// Адрес получателя /* Создание сокета и присвоение значения дескриптору сокета для UDP пакетов * PF_INET - IP protocol family * SOCK_DGRAM - Raw protocol interface */ if ((m_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); return -1; } /* Обнуляем переменную m_addr и забиваем её нужными значениями */ bzero(&m_addr, sizeof(m_addr)); m_addr.sin_family = AF_INET; // обязательно AF_INET! m_addr.sin_port = htons(0); // 0 - выдать порт автоматом /* Переводим адрес в нужный нам формат */ if (inet_aton(my_addr.c_str(), &m_addr.sin_addr) == 0) { perror("inet_aton"); close(m_sock); return -1; } /* Биндим сокет */ if (bind(m_sock, (struct sockaddr*)&m_addr, sizeof(m_addr)) < 0) { perror("bind"); close(m_sock); return -1; } /* Обнуляем переменную s_addr и забиваем её нужными значениями */ bzero(&s_addr, sizeof(s_addr)); s_addr.sin_family = AF_INET; s_addr.sin_port = htons(1024); /* Переводим адрес в нужный нам формат */ if (inet_aton(ip_addr.c_str(), &s_addr.sin_addr) == 0) { perror("inet_aton"); close(m_sock); return -1; } /* Засыпаем адресата пачкой пакетов */ char msg[1024] = "hey, hey baby! whoh-whah! i wanna kno-o-ow if you'll be my girl."; while(1) { if (sendto(m_sock, msg, 1024, MSG_NOSIGNAL, (struct sockaddr*)&s_addr, sizeof(s_addr)) < 0) { perror("sendto"); close(m_sock); return -1; } sleep(1); } /* Закрываем сокет и выходим из программы */ close(m_sock); return (EXIT_SUCCESS); } Код программы-сервера: #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string> #include "string.h" using namespace std; int main(int argc, char** argv) { int m_sock; // дескриптор сокета sockaddr_in m_addr; // переменная адреса интерфейса string my_addr = "192.168.0.90";// Адрес локального интерфейса /* Создание сокета и присвоение значения дескриптору сокета для UDP пакетов * PF_INET - IP protocol family * SOCK_DGRAM - Raw protocol interface */ if ((m_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); return -1; } /* Обнуляем переменную m_addr и забиваем её нужными значениями */ bzero(&m_addr, sizeof(m_addr)); m_addr.sin_family = AF_INET; // обязательно AF_INET! m_addr.sin_port = htons(1024); // 0 - выдать порт автоматом /* Переводим адрес в нужный нам формат */ if (inet_aton(my_addr.c_str(), &m_addr.sin_addr) == 0) { perror("inet_aton"); close(m_sock); return -1; } /* Биндим сокет */ if (bind(m_sock, (struct sockaddr*)&m_addr, sizeof(m_addr)) < 0) { perror("bind"); close(m_sock); return -1; } /* Получаем пакеты от отправителя */ char recvline[1024]; int bytesrecv; while(1) { if ((bytesrecv = recvfrom(m_sock, recvline, 1024, 0, (sockaddr*)NULL, NULL)) < 0) { perror("recvfrom"); close(m_sock); return -1; } printf("Message received! Size: %d\n", bytesrecv); } /* Закрываем сокет и выходим из программы */ close(m_sock); return (EXIT_SUCCESS); } Ни единого recvfrom не произошло, хотя пришла уже не одна тысяча пакетов. Кусок лога WireShark, который повторяется каждую секунду: Цитата 192.168.0.211 192.168.0.90 UDP Source port: 35160 Destination port: 1024 192.168.0.90 192.168.0.211 ICMP Destination unreachable (Host administratively prohibited) PS: 192.168.0.90 - ip моего компа 192.168.0.211 - ip удалённой тачки Обмен данными производится через 1024 порт. PPS: Поначалу грешил на порт, пробовал менять его на меньший и больший - ничего не меняется. PPPS: Грешил на адрес интерфейса, пробовал делать my_addr.sin_addr.s_addr = htonl(INADDR_ANY) - тоже никакого эффекта. |
Сообщ.
#2
,
|
|
|
Цитата gabbear @ FirewallICMP Destination unreachable (Host administratively prohibited) Цитата gabbear @ Для клиента это лишнее. /* Биндим сокет */ Цитата gabbear @ Должно менятся. Или ты сидишь по root'ом? Поначалу грешил на порт, пробовал менять его на меньший и больший - ничего не меняется. |
Сообщ.
#3
,
|
|
|
Цитата albom @ Цитата gabbear @ FirewallICMP Destination unreachable (Host administratively prohibited) Хм. А почему тогда сниффер эти пакеты ловит? Цитата albom @ Цитата gabbear @ Должно менятся. Или ты сидишь по root'ом? Поначалу грешил на порт, пробовал менять его на меньший и больший - ничего не меняется. Пробовал и под рутом и без него - точно так же пакеты идут, сниффер их ловит, ICMP ответ уходит, сервер ничего не видит. |
Сообщ.
#4
,
|
|
|
Это к тому, что не root'у нельзя биндить порт с номером меньше 1024. Изменение должно быть в виде ошибки в сервере при вызове bind().
Цитата gabbear @ Потому что переводит карту в promiscuous режим и слушает весь сетевой поток, а не работает на уровне пакетов как firewall. А почему тогда сниффер эти пакеты ловит? |
Сообщ.
#5
,
|
|
|
Цитата albom @ Это к тому, что не root'у нельзя биндить порт с номером меньше 1024. Изменение должно быть в виде ошибки в сервере при вызове bind(). Цитата gabbear @ Потому что переводит карту в promiscuous режим и слушает весь сетевой поток, а не работает на уровне пакетов как firewall.А почему тогда сниффер эти пакеты ловит? Спасибо большое. Вчера тряс нашего админа на тему всяческих фаерволов и сетевых фильтров - убеждал, что нигде ничего. Но почему-то оказался включён фаервол. Заработало. |