как узнать обратный адрес пакета,
полученного с помощью recv() или read() ?
(recvfrom не предлагать :)
Спасибо!
PS Извините за глупый вопрос :)
Усе просто:
sockaddr_in addr; getpeername(sock,&addr,sizeof(sockaddr_in));
во всяком случае, судя по инфам, должно робить...
Дело в том, что над socket-ом не была
проведена операция connect ->
поэтому вызывается error:
Socket not connected
или похожими словами :)
ну, там, вроде, еще есть чтой-то типа recvmsg, но этого я уже не помну :) см man recv :) или там в info тож чего-то, помнится, есть... даже немного подробней :)
Да, но мне нужно именно read().
Я перехватываю IO опереации над сокетами
и заранее не знаю какой функцией чтения
пользуется application.Еще идеи ?
Стоп. С чем работает read и recv ? Правильно, только с сокетами, которые требуют соединения и имеют установленное соединение ! В частности, по протоколу TCP или UNIX-сокеты. А ты пытаешься примениять их ко всем сокетам ? Оригинально.
И что это за application ?
вышеназванные вызовы работают
и без соединения.
Пример -- UDP датаграммы.
А application - tftpd.
Хм... Кусок мана:The recv call is normally used only on a connected socket (see connect(2)) and is identical to recvfrom with a NULL from parameter.
...
ну так ты гляди - видишь "normally"? :)))
а если "unnormally", то все подряд :))) только надо знать, как... Для того, чтобы знать, надо читать не только man, но и шарить по исходникам :)))).
Как сказал однажды один человек (вроде бы, RZ), Unix - это один здоровый фильтр. Так вот, в системных вызовах типа "recv" и т.п. можно указывать (куда бы и как бы ни был прикручен сокет, даже если он просто открыт и не прикручен) любой способ фильтрации, применимый к конкретному случаю; а recvmsg является и фильтром, и запихивает в структуру все че можно об мессаге.
Во всяком случае, вышесказанное было верно для Linux'a на 2.2.17-м ядре :))).
О ! В самом конце ты приблизился к сути :))
Откуда ты знаешь, что в последующих ядрах будет точно так же ? Откуда ты знаешь, что в 2.2.17-ac1, например, не пропатчили это дело ?
Не будешь же ты лазить по исходникам каждого нового ядра или патча, чтобы посмотреть как оно там сейчас работает :))
Скажу так: я не знаю :) но предполагаю, что это не изменится с появлением новых ядер. Просто, как мне кажется, эти пути являются достаточно стандартными и патчить их никто не будет :), просто тогда многие полезные утилки перестанут работать :)
Хех :))
А как же переход с libc5 на libc6 ? Или забылыли уже, сколько было траха с переносом программ ? Приходилось держать обе версии либ, чтобы более менее работать нормально.
man 3 recv для (SCO UnixWare 7.1.1):...socket is a socket file descriptor that has been created using socket. recv, recvfrom, and recvmsg are used to receive messages from another socket. recv may be used only on a connected
-------------------------^^^^
socket see connect(3sock)), while recvfrom and recvmsg may be used to receive data on a socket whether it is in a connected state or not. recvfrom is commonly used with connectionless sockets because it аllows the source address to be extracted from received data.Вот так во всяком случае сказано в SCO. Никаких recv без connect. Установи соединение, и работай. Хочешь без соединения - работай через SOCK_DGRAM и recvfrom.
Васа, слушай, да ты ЗВЕРР :) А как ты ловишь соединения??? Делись опытом :) а то я ламерр, но учиться хочу :) А recvmsg помогает? Или нет? ведь там же в msghdr закидывается, вроде, адрес отправителя?
[font size="1" color="#FF0000"]Последняя редакция от 28-Июл-01 02:41 ()[/font][p]>Васа, слушай, да ты ЗВЕРР :)
>А как ты ловишь соединения???
>Делись опытом :) а то
>я ламерр, но учиться хочуЭто в QNX6. Как в других операционках -- не знаю.
В Linux & Net/Free-BSD -- возможно -- divert сокеты или BPF.
В общем -- побитые пакеты :(
Но это только догадки -- я тут далеко не спец.
Может, кто другой знает.>:) А recvmsg помогает? Или
>нет? ведь там же в
>msghdr закидывается, вроде, адрес отправителя?
Должно, но не хочется пользоваться дополнительными функциями i/o. Тем более, что это работает только с RAW socket-ами (в QNX по кр.мере). Тогда вообще придется прослушивать весь трафик на RAW уровне - тогда, конечно можно без труда достать этот адрес -- но много лишних телодвижений...
В общем -- насколько я понимаю, в чистом пакете есть обратный адрес -- значит его можно получить без всяких таких трудоемких вывертов (тем более что все это занимает процессорное время, а это нужно не для игрушек). Я предполагал, что существует какой-н. код для ioctl()-вызова...
В самом TCP пакете есть обратный адрес это 32 бита с начиная с 95-ого (отсчет с 0 бита), его наверное просто нужно извлеч от туда.
И как же его узнать, если ты открыл UDP socket и получил этот пакет ?
Наверное имелся ввиду не TCP, а IP, который является транспортом для TCP и UDP.
Че то я не понял как ты все делаешь, но если ты читаешь из сети _кадры_ (пакеты), и сеть ethernet стандарта 802, то физический адрес назначения первые 6 октетов, следющие 6 -- адрес источника.
Тут речь зашла о TCP и UDP. Затем об IP. Но все они находятся выше раскадровки по модели OSI. Так что, народ читает из сети не кадры, а уже собранные пакеты. В частности, относящиеся к семейсву IP. А вот IP собирается из кадров. Если я правильно помню, то модель OSI делится на такие уровни:
физический, канальный, транспортный, сеансовый, сетевой, уровень согласования и прикладной.
Так вот протоколы TCP и UDP относятся к сетевому уровню (или сеансовому - точно не помню), протокол IP - к транспортному, а кадры - к канальному. То есть, физический адрес карты ты вообще не знаешь - он до тебя просто не доходит.
Ты можешь его видеть только на уровне сокета PF_PACKET, а не PF_INET.
>Тут речь зашла о TCP и
>UDP. Затем об IP. Но
>все они находятся выше раскадровки
>по модели OSI. Так что,
>народ читает из сети не
>кадры, а уже собранные пакеты.
>В частности, относящиеся к семейсву
>IP. А вот IP собирается
>из кадров. Если я правильно
>помню, то модель OSI делится
>на такие уровни:
>физический, канальный, транспортный, сеансовый, сетевой, уровень
>согласования и прикладной.
>Так вот протоколы TCP и UDP
>относятся к сетевому уровню (или
>сеансовому - точно не помню),
>протокол IP - к транспортному,
>а кадры - к канальному.
>То есть, физический адрес карты
>ты вообще не знаешь -
>он до тебя просто не
>доходит.
>Ты можешь его видеть только на
>уровне сокета PF_PACKET, а не
>PF_INET.
Vasa, ты с какого уровня достаешь пакеты?
О порядке уровней и их функциях ты немного неправ.Модель OSI:
1. Физический
2. Канальный
3. Сетевой
4. Транспортный
5. Сеансовый
6. Презентационный
7. ПрикладнойПротокол ip относят к "Сетевому уровню", tcp и udp к "Транспортному уровню"
Вообще я программированием для сетей особенно не занимался, но надо смотреть заголовок IP.
Вполне возможно - давно это было :))
Для получения адреса с уровня TCP/UDP нужно просто доку почитать :))А кстати, в какой уровень впихивается ICMP ? По идее, он относится к семейству IP, но находится ниже TCP/UDP. В смысле, ближе к физике :))
>Вполне возможно - давно это было
>:))
>Для получения адреса с уровня TCP/UDP
>нужно просто доку почитать :))))))))))))
>
>
>А кстати, в какой уровень впихивается
>ICMP ? По идее, он
>относится к семейству IP, но
>находится ниже TCP/UDP. В смысле,
>ближе к физике :))ICMP, находится на том же уровне, что и IP, сетевом.
Да ? Так что же, получается, на одном уровне находятся 2 одинаковых протокола ? Ведь ICMP входит в семейство IP.
>Да ? Так что же, получается, на одном уровне
>находятся 2 одинаковых протокола ? Ведь ICMP
>входит в семейство IPПочти так. Тут вот в чем дело, есть различия в иерархиях TCP/IP и OSI.
OSI -------------------------> TCP/IP
1. физический и
2. канальный -------------> Network (сетевой)
3. сетевой -----------------> Internetwork (межсетевой)
4. транспортный --------> Transmission (транспортный)
5...IP и ICMP находятся на уровне Internetwork по классификации TCP/IP и на Сетевом уровне классификации OSI.
Уровень, один но функции у них разные :))
ICMP попадает на этот уровень УСЛОВНО т.к. явно не является транспортным протоколом (точно лежит ниже), но это и не физический/канальный уровень (лежит выше). Как раз попадает под сетевой/межсетевой :))
Ясно.
Поделись урлом откуда инфу можно взять :))
>Ясно.
>Поделись урлом откуда инфу можно взять
>:))Урл не знаю. Это я из головы вспомнил:))) скорее всего здесь на opennet.ru должно что то должно быть.
> как узнать обратный адрес пакета,
>
> полученного с помощью recv() или
>read() ?
> (recvfrom не предлагать :)
>Спасибо!
>PS Извините за глупый вопрос :)
>
Ну развели здесь, OSI/ISO, raw, datalink... :) Кто сказал, что connect нельзя применять к udp-сокетам? Оччень даже можно, причем, в отличие от tcp, не только к клиентским, но и к серверным! При этом, конечно, никакого 3-way handshake инициализировано не будет, ибо в udp такого вообще нет. Просто при этом сокет будет получать только датаграммы с того удалённого сокета, к коему он "приконнекчен". Так вот мораль: recvfrom можно юзать с неприконнекченными udp-сокетами, а recv - только с приконнекченными, для которых адрес удалённой стороны был задан при системном вызове connect.
Ну, дык! Наконец здравый человек нашелся!!
Хех. А я думал, что народ пытается выяснить адрес удаленной машины, от которой получены данные. И при этом даже не подозревают, что он хранится в структуре sockaddr_in, которая заполняется в программе для вызова connect и sendto, или заполняется функциями accept и recvfrom при получении данных :))
Остается только посмотреть в переменную sockaddr_in.sin_addr.s_addr :))
:)))))))))))))))))))))