LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 05-07-2008, 11:37 AM   #1
baddad
LQ Newbie
 
Registered: May 2008
Posts: 15

Rep: Reputation: 0
Question RAW receive Socket also delivers sent frames


Hi All!

This is my first time posting so please be patient ;-)

I am sending Ethernet frames through RAW Sockets.

At the same time I want to listen, using a RAW socket, for incoming traffic, but without receiving the frames sent through the same NIC.

Everything works fine when using different NICs for sending and receiving, but this is not applicable for me.

I tried all combinations of the commented and uncommented configurations below for the receiving socket. Everytime I also received the sent frames.

Code:
//Creating RAW Ethernet Socket
	int SOCKET_ID = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	//int SOCKET_ID = socket(PF_UNSPEC, SOCK_DGRAM, htons(ETH_P_ALL));
	//int SOCKET_ID = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));

	//socket config
	struct sockaddr_ll socket_address;
	socket_address.sll_family = AF_PACKET;
	//socket_address.sll_family = AF_UNSPEC;
	socket_address.sll_protocol = htons(ETH_P_ALL);
	socket_address.sll_ifindex = IF_INDEX;
	socket_address.sll_pkttype = PACKET_OTHERHOST|PACKET_BROADCAST|PACKET_MULTICAST|PACKET_HOST;
	//socket_address.sll_pkttype = PACKET_HOST;
	socket_address.sll_halen = ETH_ALEN;
	socket_address.sll_hatype = 0x0000; 

	//bind socket to NIC by IF_INDEX
	int bind_res = bind(SOCKET_ID,(struct sockaddr* )&socket_address,sizeof(socket_address));

	//configure promiscious mode
	struct packet_mreq pmreq;
	pmreq.mr_ifindex = IF_INDEX;
	pmreq.mr_type = PACKET_MR_PROMISC;
	//pmreq.mr_type = PACKET_MR_ALLMULTI;
	pmreq.mr_alen = ETH_ALEN;
	//pmreq.mr_address[8] = (unsigned long) 0x010ECF000000;
	int sock_opt_res = setsockopt(SOCKET_ID,SOL_PACKET,PACKET_ADD_MEMBERSHIP,(struct packet_mreq*)&pmreq,sizeof(pmreq));
Any Ideas? What about IOCTLs? But I donīt know how to use them...

If anyone could help, this would really save my day!

Last edited by baddad; 05-07-2008 at 11:42 AM. Reason: Just for fun!
 
Old 05-07-2008, 02:56 PM   #2
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,536

Rep: Reputation: 148Reputation: 148
IMO try:
int SOCKET_ID = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));

ETH_P_ALL used to (at least in the past) give you both directions.
 
1 members found this post helpful.
Old 05-07-2008, 05:55 PM   #3
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,978
Blog Entries: 11

Rep: Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879
Moved: This thread is more suitable in <PROGRAMMNIG> and has been moved accordingly to help your thread/question get the exposure it deserves.
 
Old 05-08-2008, 01:24 AM   #4
baddad
LQ Newbie
 
Registered: May 2008
Posts: 15

Original Poster
Rep: Reputation: 0
Post Another Protocol Type

Thanx Mara,

but what I want to do, is sending RAW Layer 2 Ethernet Frames, not Layer 3 IP Packets.

But maybe your Idea goes into the right direction by varying different protocol types. This is what I havenīt tried until now!
All the tutorials and other sources used this ETH_P_ALL type when creating RAW sockets, so I thought this is mandatory.

Iīll let you know if it helped.
 
Old 05-08-2008, 02:39 AM   #5
baddad
LQ Newbie
 
Registered: May 2008
Posts: 15

Original Poster
Rep: Reputation: 0
Thumbs down Did not help

Hi!

I tried the following protocol types:

ETH_P_802_3
ETH_P_802_2
ETH_P_TR_802_2
ETH_P_IP

When using ETH_P_IP I received at least some Pings, but not any cooked Layer2 frame, what did not really surprise me.

All the other configurations did not let me receive any frame at all.

Again, when I use ETH_P_ALL I also receive the frames I sent through the same NIC.

Normally you adjust the received packet type through

Code:
//socket config
struct sockaddr_ll socket_address;
...
socket_address.sll_pkttype = PACKET_OTHERHOST|PACKET_BROADCAST|PACKET_MULTICAST|PACKET_HOST;
//socket_address.sll_pkttype = PACKET_HOST;
...

//bind socket to NIC by IF_INDEX
int bind_res = bind(SOCKET_ID,(struct sockaddr* )&socket_address,sizeof(socket_address));
right? But this seem to have no effect at all!

I even tried several different NIC-types.
 
Old 05-08-2008, 09:59 AM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
As I understand it, using raw socket mode puts the interface into 'promiscuous' mode. The upshot of this is that it receives all ethernet frames. This is the mode used by network sniffers and similar tools. If you look in your syslog log files, you will probably see evidence of this.
--- rod.
 
Old 05-09-2008, 09:36 AM   #7
baddad
LQ Newbie
 
Registered: May 2008
Posts: 15

Original Poster
Rep: Reputation: 0
Unhappy I also tried other modes...

Thanx theNbomr!

Over the Weekend I dont have access to the logs, but I will verify, if the NIC goes into promisciuos mode next week!

But I also tried the following: creating a standard "SOCK_DGRAM"

Code:
int SOCKET_ID = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
//socket config
struct sockaddr_ll socket_address;
socket_address.sll_family = AF_PACKET;
socket_address.sll_protocol = htons(ETH_P_ALL);
socket_address.sll_ifindex = IF_INDEX;
socket_address.sll_pkttype = PACKET_OTHERHOST|PACKET_BROADCAST|PACKET_MULTICAST|PACKET_HOST;
socket_address.sll_halen = ETH_ALEN;
socket_address.sll_hatype = 0x0000;
Still receiving the outgoing frames!

Following the man-pages, the packet type to be received is controlled by "sll_pkttype" of the "sockaddr_ll" structure (check out "man 7 packet" to review the options).
Why does this not affect any socket? Either it is not implemented or I need a psychiatrist

Last edited by baddad; 05-09-2008 at 09:39 AM.
 
Old 05-14-2008, 01:24 AM   #8
baddad
LQ Newbie
 
Registered: May 2008
Posts: 15

Original Poster
Rep: Reputation: 0
Question Where to find it?

Hi again!

Where to find the appropriate logfile to check whether the NIC goes into promiscious mode?

Did I forget to say, that I am not that used to Linux?
 
Old 05-14-2008, 09:08 AM   #9
baddad
LQ Newbie
 
Registered: May 2008
Posts: 15

Original Poster
Rep: Reputation: 0
Cool Workaround

Since nobody could help I made a little workaround

I filtered the frames with the same source MAC than the current receive sockets NIC.

Unfortunately this decreases the overall performance a little bit and forces me to use always the real MAC adress of the NIC I am sending from! With a little more effort I could solve this problem too, but with the allocation of even more administration expense!

So thank you all anyway!
 
Old 05-14-2008, 11:55 AM   #10
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
Your packet type does look correct to me. Are you sure that you are not sending broadcasts or multicasts, which your packet type should be receiving?
Where syslog sends it's messages is a local matter, but on my Scientific Linux (RHEL clone) I see messages in my /var/log/messages file like:
Code:
May  7 11:14:54 xxxxxxpc kernel: eth0: Setting promiscuous mode.
May  7 11:14:54 xxxxxxpc kernel: device eth0 entered promiscuous mode
May  7 11:15:01 xxxxxxpc kernel: device eth0 left promiscuous mode
May  8 09:30:40 xxxxxxpc kernel: eth0: Setting promiscuous mode.
May  8 09:30:40 xxxxxxpc kernel: device eth0 entered promiscuous mode
May  8 09:30:52 xxxxxxpc kernel: device eth0 left promiscuous mode
--- rod.

Last edited by theNbomr; 05-14-2008 at 11:56 AM.
 
Old 05-18-2008, 05:13 AM   #11
baddad
LQ Newbie
 
Registered: May 2008
Posts: 15

Original Poster
Rep: Reputation: 0
Thumbs down

Hi Rod!

Since it is my basic intention for all of this, to manually create Layer 2 frames, I tried all kinds of frames. Broadcasts, Multicasts and Unicasts.

Unfortunately all with the same result.

Through IOCTLs I can configure the socket to receive either one or several of them, but this has just effect for the received frames from other stations. The ones I send by myself, I always receive, disregarding the type.

Seems like the filter in my program is the only way to do it.
 
Old 05-22-2008, 12:48 PM   #12
xamitksx
LQ Newbie
 
Registered: May 2008
Posts: 5

Rep: Reputation: 0
Hi i am also facing the same problem with RAW socket i am reciving all transmitted pkts form all fo the interfaces

code
raw_sock =socket( AF_PACKET , SOCK_RAW, htons(ETH_P_ALL)) ;
setsockopt(raw_sock , SOL_SOCKET , SO_BINDTODEVICE , "eth1" , strlen("eth1")+ 1 );

/**setting the eth1 in promiscous mode this part is working fine /

while(foreever)
{
recvform(...)
}
i have few doubts
1) can i use socket( AF_PACKET , SOCK_RAW, htons(ETH_P_IP ||ETH_P_ARP ))
as i am interested in arp and ip packets WHy shalli listen all packet
IS it nay good approach to do that ??
2)what is difference between using bind() and SO_BINDTODEVICE please tell pros and cons of each??
3)
 
Old 05-22-2008, 04:37 PM   #13
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
Here is a code fragment that works for me. Hopefully the variable names and so on make it overall readable.
Code:
    /* Attempt to open the socket for 802.2 ethernet frames 
    */

    /* this should be updated to the newer PF_PACKET interface 
    */
    // if ((sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_802_2))) < 0)
    if ((sock_fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_802_2))) < 0)
    {
        /* Error occured */
        error_printf("ethernet: Error opening socket : %s\n", strerror(errno));
        exit(-1);
    }

    debug_printf(2, "ethernet: 802.2 socket open on file descriptor %d\n", sock_fd);

    /* Bind the socket to an address 
    */
    eth_addr->sa_family = AF_UNIX;

    /* Clear the memory before copying 
    */
    memset(eth_addr->sa_data, '\0', sizeof(struct sockaddr_in));

    /* Strcpy the interface name into the address 
    */
    strncpy(eth_addr->sa_data, interface_name, IFNAMSIZ);       /* IFNAMSIZ == 14 */

    /* Attempt to bind the socket to the interface 
    */
    if (bind(sock_fd, eth_addr, sizeof(struct sockaddr)) != 0) {
        /* Bind problem, close socket and return 
        */
        error_printf("ethernet: Unable to bind 802.2 socket : %s\n",
            strerror(errno));
        /* Close the socket 
        */
        close(sock_fd);
        exit(-1);
    }

    debug_printf( 2, "ethernet: 802.2 socket bound to %s\n", interface_name);
I recall trying to get the PF_PACKET interface type to work, but failed, and I never got around to tracking that whole problem down. This code has been in production at my site since 2004. It is part of the bacnet4linux project which can be found on sourceforge.
--- rod.
 
Old 05-23-2008, 12:36 PM   #14
xamitksx
LQ Newbie
 
Registered: May 2008
Posts: 5

Rep: Reputation: 0
have few doubts
1) can i use socket( AF_PACKET , SOCK_RAW, htons(ETH_P_IP ||ETH_P_ARP ))
as i am interested in arp and ip packets WHy shalli listen all packet
IS it nay good approach to do that ??
2)what is difference between using bind() and SO_BINDTODEVICE please tell pros and cons of each??
 
Old 05-24-2008, 01:56 AM   #15
baddad
LQ Newbie
 
Registered: May 2008
Posts: 15

Original Poster
Rep: Reputation: 0
Post

Hi Rod, Hi xamitksx!

- Since you receive all frames from all interfaces I assume, that the SO_BINDTODEVICE option is not working so well. Unfortunately, I did not try this option at all, so I can't tell you any pros or conts. Have you tried the bind function? It works well for me! You have to purchase the Interfaces' index to make it work correctly.

- make sure to write htons(ETH_P_IP|ETH_P_ARP ) not htons(ETH_P_IP|| ETH_P_ARP ) since the second approach forces a logical OR not a bitwise!
Using the option htons(ETH_P_IP|ETH_P_ARP )) looks good to me, just give it a try, I would say :-) Unfortunately I don't have access over the weekend to my UNIX system, so I can't give you any assistance on that, too. Sorry again for that!

- The solution I figured out was to manually filter out the sent frames by comparing the source MAC address with the local one. If you have more than one NIC, you have to do it for all of them.


Regards
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Raw socket programming with C arabindav Programming 17 06-09-2011 11:58 AM
Raw socket programming homePBX Linux - Networking 6 05-02-2008 12:25 PM
raw socket/ip packet help shouup Programming 14 04-24-2006 04:54 PM
Socket Raw linuxanswer Programming 1 04-01-2004 09:43 PM
raw socket permition moonloader Linux - Networking 2 12-08-2003 09:20 AM


All times are GMT -5. The time now is 03:40 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration