The OpenNET Project / Index page

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

SOCK_RAW (raw socket)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: raw, socket,  (найти похожие документы)
_ RU.LINUX (2:5077/15.22) ___________________________________________ RU.LINUX _ From : Sergey I. Clushin 2:5020/400 14 Apr 99 00:57:06 Subj : SOCK_RAW ________________________________________________________________________________ From: "Sergey I. Clushin" <serg@aviacom.ru> Andrey Kuzmin wrote: > > ... > >Использовать SOCK_PACKET. > > > > А можно поподробнее, т.к. когда я ставлю SOCK_PACKET вместо SOCK_RAW SOCK_PACKET Forum: The Linux Kernel Hackers' Guide Re: Difference between SOCK_RAW SOCK_PACKET (Chris Leung) Keywords: SOCK_PACKET Date: Wed, 10 Jun 1998 18:01:01 GMT From: Eddie Leung <edleung@uclink4.berkeley.edu> Body-URL: http://www.senie.com/dan/technology/sock_packet.html f78 Using the SOCK_PACKET mechanism in Linux To Gain Complete Control of an Ethernet Interface Daniel Senie Amaranth Networks, Inc. I have put together this web page in response to many queries from multiple people. Rather than continue to write individual responses, I have put together this page to explain what I was trying to do, and how I got it to work. First, some background. To simulate software that was intended to run on a different (and not yet built) platform, I needed a convenient way to exercise the code against live networks. I first tried using a Solaris system, using the DLPI driver. This allowed me to do most things, but failed when I needed to be able to set the source Ethernet MAC address. The Solaris DLPI driver provides no way to override the hardware on a per-packet basis. Next, I started looking at mechanisms in Linux. The mechanism that seemed to fit the best was SOCK_PACKET, which is used by tcpdump among other things. To Make this work for me, though, it was necessary to keep the Linux machine from doing anything on the interface, other than letting my programs at it. How To Do It This information and these instructions work for RedHat Linux 4.2 with a 2.0.30 kernel. I expect they'll work fine on a 2.0.32 kernel as well, and with other Linux distributions. I have heard that a better mechanism for providing this facility is coming in a newer kernel. If or when I get more information on that, I'll see about adding another page on that. First, the interface needs to be told NOT to run ARP. Promiscuous mode should be enabled if you need to hear everything on the wire.: ifconfig eth1 -ARP PROMISC UP 10.1.1.1 Then tell the Linux stack it's not supposed to see any of the traffic to or from this port: ipfwadm -O -a deny -P all -S 0/0 -D 0/0 -W eth1 ipfwadm -I -a deny -P all -S 0/0 -D 0/0 -W eth1 In the program, you need to do several things. First, the socket call: s = socket(AF_INET, SOCK_PACKET, htons(0x0003)); to get the socket set up. Next I bind the specific Ethernet NIC I want: struct sockaddr myaddr; memset(&myaddr, '\0', sizeof(myaddr)); myaddr.sa_family = AF_INET; strcpy(myaddr.sa_data, "eth1"); /* or whatever device */ r = bind(s, &myaddr, sizeof(struct sockaddr)); and check the return code for any errors. Now, when you want to send or receive, this socket is bound to the proper device. One word of caution, though, ALWAYS check the received packets to be sure you got them on the right device. There's a race condition between making the socket call and the bind call where you'll get all packets from ALL interfaces... not what you want! So, to send a packet: struct sockaddr from; int fromlen; memset(&from, '\0', sizeof(from)); from.sa_family = AF_INET; strcpy(from.sa_data, "eth1"); /* or whatever device */ fromlen = sizeof(from); r = sendto(s, msg, msglen, 0, &from, fromlen); and check the return code. Note that msg is the pointer to the packet, starting with the MAC header. Be sure you put the proper source MAC address into your packets! Also, msglen is the length of the packet including the MAC header, but not including the CRC (which I do not worry about, but the hardware does supply). Receive is pretty similar: struct sockaddr from; int fromlen; fromlen = sizeof(from); r = recvfrom(s, msg, 2048, 0, &from, &fromlen); if (r == -1) { /* deal with error */ } if 5fc (strcmp(from.sa_data, "eth1") != 0) { /* not from the interface we wanted, discard */ } if r == -1, you have an error. If r > 0, then r is the length of the received packet. The strcmp ensures the packet came from the right interface. If you want to receive for MAC addresses other than the one the board has in it, use promiscuous mode. To get the mac address from your program, there's an ioctl call SIOCGIFHWADDR. In the return from that call is also the hardware type, so you can ensure it's Ethernet. Another call, SIOCGIFMTU will tell you the MTU of the interface. Caveats Do not use this methodology on your primary Ethernet interface. Instead, install a second (and if needed, third) NIC card for use in this way. I've successfully used 5 NIC cards in one machine, 1 under the control of Linux, the rest bypassed to my programs. Be VERY sure you set up the ipfwadm commands. Failure to do so will make a huge mess, likely causing networking problems for other hosts on your lan. If you found this information helpful and useful, please let me know. If you require further information or assistance in this area, this can be arranged. For consultation beyond simple questions, Amaranth Networks, Inc. can provide advice, services and information for a fee. Copyright Э 1998, Amaranth Networks, Inc. All Rights Reserved 0 Предупреждение относительно primary eth можете смело игнорировать. > то sendto возвращает -1 и ничего не посылает И вообще, почему-бы Вам не посетить KHG - Kernel Hacker's Guide. Раньше он была на http://www.redhat.com:8080/HyperNews/get/khg.html Там в вопросах и ответах много ценного есть. В том числе и ответ на Ваш вопрос: Difference between SOCK_RAW SOCK_PACKET. > ... (галиматья выкинута) > > Спасибо. Кушайте на здоровие. Да, еще можете посмотреть tcpdump. В его исходниках етсь исходниоки libpcap, а в ней используется SOCK_PACKET. Еще можете Стивенса почитать, последнюю редакцию; там про SOCK_PACKET в Линухе тоже есть. -- Best regards. Sergey. Всего хорошего. Сергей. --- ifmail v.2.14dev3 * Origin: private person (2:5020/400)

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий
Имя:
E-Mail:
Заголовок:
Текст:




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

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