LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
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 09-26-2010, 05:44 AM   #1
mehdiizadeh
LQ Newbie
 
Registered: Jun 2007
Posts: 9

Rep: Reputation: 0
How to send UPD packets to Neighbor MacAddress


Hi

I want to send Received UDP Packets to neighbor MAC Address.
Anyone can guide me to how to do it?

I can received UDP packets and then forward to unicast address as follow:
How can i modify this codes (Maybe Last Line) to send the received packets to destination MAC Address instead of destination IPv6 Address?

Code:
int main(int argc, char ** argv)
{
	int s,s1;
	struct sockaddr_in6 a,a1;
	
	if (argc != 4) {
					fprintf(stderr, "USAGE: unicast_recv udp_port MAC_Add Forward_MAC_Port\n");
					exit(-1);
				   }
	
	memset(&a, 0, sizeof(a));
	a.sin6_addr = in6addr_any;
	a.sin6_port = htons(atoi(argv[1]));
	s = socket(AF_INET6, SOCK_DGRAM, 0);

	if (s < 0) {
				perror("socket");
				exit(-1);
			   }	
	
	if (bind(s, (struct sockaddr*)&a, sizeof(a)) < 0)
	  {
		perror("bind");
		exit(-1);
	  }

	//Open New Port for Sending Packets to MAC Address
    s1 = socket (AF_INET6, SOCK_DGRAM, 0);
    if (s1<0) {
                perror("socket");
                exit(-1);
               }
     memset (&a1, 0, sizeof(a1));
     a1.sin6_port = htons (atoi(argv[3]));
     if (inet_pton (AF_INET6, argv[2], &a1.sin6_addr) <= 0)
                 {
                  perror ("inet_pton");
                  exit(-1);
                 }
     a1.sin6_family = AF_INET6;
        // End of Opening New Port

	
	while (1) {
				unsigned char buffer[2000], pkt_flg[100];
				int i;
				struct timeval now;
				struct sockaddr_in6 mcast_addr;
				int addr_len = sizeof(struct sockaddr_in6);
				gettimeofday(&now, NULL);
				
				i = recvfrom(s, buffer, 2000, 0, (struct sockaddr_in6*)&mcast_addr, &addr_len);

				if (sendto(s1, buffer, 1400, 0, (struct sockaddr_in6*)&a1, sizeof(a1)) == -1)
				perror("sendto");
			 }
}

Your help would be highly appreciated.
 
Old 09-26-2010, 10:25 AM   #2
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
If you are trying to use the MAC as the destination, you can send raw packets, and format them as UDP yourself. If you can't use root privileges required to send raw packets, then you will have to lookup the IP by MAC, and send UDP packets. You would then have to use some hackery to determine the IP of the host by reverse lookup of the IP from the MAC. arp will list all of the IPs & MACs already known to your IP stack, however the target IP isn't guaranteed to exist in the arp table at any given time. You can use a brute force method to get MACs into the arp table by doing something like a ping of every IP in the range you think your target host is in, and then checking the arp table to find the target MAC.

Your request seems highly unusual. What are you really trying to accomplish?

--- rod.
 
Old 09-27-2010, 11:44 PM   #3
mehdiizadeh
LQ Newbie
 
Registered: Jun 2007
Posts: 9

Original Poster
Rep: Reputation: 0
Thanks theNbomr

Quote:
If you are trying to use the MAC as the destination, you can send raw packets, and format them as UDP yourself.
I should format them as UDP at destination, right?

I can use root privileges...
If i get somehow the MAC of destination host, how can i forward a received packet as raw packet to that particular MAC address?
Could you please look at the following command where i received a "buffer" from one host? and tell me how to forward this buffer to a destination known MAC address.

Code:
i = recvfrom(s, buffer, 2000, 0, (struct sockaddr_in6*)&mcast_addr, &addr_len);
Best Regards
 
Old 09-28-2010, 10:18 AM   #4
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Quote:
I should format them as UDP at destination, right?
Not sure exactly what you mean by this. If you want the destination host to receive the packet as a UDP datragram, then you would have to format it as such. That, of course, begs the question of why you wouldn't simply send it as a UDP datagram using the existing IP stack. The whole premise of your objective seems peculiar in this sense.

You use SOCK_RAW type (man socket) to send raw ethernet datagrams. In that case, your destination address is specified as a MAC, as the IP stack is not used to send the data. In use, the raw packet is composed, including the ethernet header containing the source and destination MACs, and all of the other fields required for a valid ethernet frame. The data received in your 'buffer' array would become part of the payload field of the ethernet frame, and would follow any UDP/IP header.
Normally, you would only want to do this to send non-IP ethernet traffic. To send IP traffic this way seems highly redundant. Why would you want to use a MAC as the basis for addressing in an IP network?

--- rod.
 
Old 09-28-2010, 10:06 PM   #5
mehdiizadeh
LQ Newbie
 
Registered: Jun 2007
Posts: 9

Original Poster
Rep: Reputation: 0
Thanks again theNbomr

Actually i want to receive the multicast packets at access point and unicast them to many MAC addresses of users instead of multicast to many IP addresses of users.

As you said, I have to use SOCK_RAW with the MAC address as destination. Can i send RAW packets to two or three MAC addresses at the same time?

Regards
 
Old 09-28-2010, 10:43 PM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
You will be sending raw ethernet frames. Each frame has one destination address, so one you need to send to each destination individually.

--- rod.
 
Old 09-29-2010, 03:59 PM   #7
jf.argentino
Member
 
Registered: Apr 2008
Location: Toulon (France)
Distribution: FEDORA CORE
Posts: 493

Rep: Reputation: 50
Quote:
Actually i want to receive the multicast packets at access point and unicast them to many MAC addresses of users instead of multicast to many IP addresses of users.
As theNbomr already said, this is a big waste of throughput. The multicast protocol is done for that, once the peer that need the stream as done the multicast group membership request, it will receive datagram (switches between emitter and receiver will forward datagram), but no forwarding before the membership request...
 
Old 10-02-2010, 11:36 PM   #8
mehdiizadeh
LQ Newbie
 
Registered: Jun 2007
Posts: 9

Original Poster
Rep: Reputation: 0
Quote:
As theNbomr already said, this is a big waste of throughput.
Thanks jf.argentino for your reply.
Yes you are right. I just want to test some scenario for my research.
So far, I've managed to send UDP packets from server, then received on another PC (say access point) and forward to destination MAC address (receiver).
here is the code to receive and forward to MAC destination on access point:

Code:
int main(int argc, char ** argv)
{
	int s;
	struct sockaddr_in6 a;
	
	if (argc != 2) {
		fprintf(stderr, "usage: recv_fw_mac udp_port\n");
		exit(-1);
	}
	
	memset(&a, 0, sizeof(a));
	a.sin6_addr = in6addr_any;
	a.sin6_port = htons(atoi(argv[1]));
	
	s = socket(AF_INET6, SOCK_DGRAM, 0);
	if (s < 0) {
		perror("socket");
		exit(-1);
	}
	
	if (bind(s, (struct sockaddr*)&a, sizeof(a)) < 0) {
		perror("bind");
		exit(-1);
	}

	printf("ser_num\trecv_time\t send_t\n");
	while (1) {
		unsigned char buffer[1400];
		int i;
		struct timeval now;
		struct sockaddr_in6 mcast_addr;
		int addr_len = sizeof(struct sockaddr_in6);
		
		gettimeofday(&now, NULL);
		i = recvfrom(s, buffer, 1400, 0, (struct sockaddr*)&mcast_addr, &addr_len);
		printf("%s\t%d.%d\t%s\n", buffer, now.tv_sec, now.tv_usec, buffer+8);

		//New Socket for MAC Forwarding.
		int s1;
		struct sockaddr_ll dstaddr;
		s1 = socket(PF_PACKET,SOCK_DGRAM,ETH_P_IP);
		if (s1<0) {
                 perror("socket");
                 return 1;
    			}

			/* now fill up the sockaddr_ll to send */
		memset(&dstaddr,0,sizeof(struct sockaddr_ll));
     
		dstaddr.sll_protocol=htons(ETH_P_IP);
		dstaddr.sll_ifindex=5;
		dstaddr.sll_hatype=ARPHRD_ETHER;
		dstaddr.sll_pkttype=PACKET_OUTGOING;
		dstaddr.sll_halen=ETH_ALEN;     /* defined as 6 */
		dstaddr.sll_addr[0]=0x00;
		dstaddr.sll_addr[1]=0x50;       /* the hw addr of the */ 
		dstaddr.sll_addr[2]=0x8D;       /* machine i want to */
		dstaddr.sll_addr[3]=0x39;       /* send it to */ 
		dstaddr.sll_addr[4]=0x5A;
		dstaddr.sll_addr[5]=0xF1;
        
		if (  sendto(s1,buffer,sizeof(buffer),0,(struct sockaddr *)&dstaddr,sizeof(struct sockaddr_ll))<0)
			 {
				 perror("sendto");
			   return 1;
			  }

		// End of New Socket

	}
}
when i check on receiver with "#tcpdump -i eth0" it shows something is receiving as follow:
Quote:
06:41:16.031701 IP3 bad-hlen 4
06:41:17.032885 IP3 bad-hlen 8
06:41:18.033772 IP3 bad-hlen 12
06:41:19.034676 IP3 bad-hlen 16
06:41:20.035562 IP3 bad-len 0
06:41:21.036457 IP3 bad-len 0
What do these mean?
I've tried to receive the RAW packets on receiver with this program but it shows nothing.

Code:
int main()
{
	int s;
	struct sockaddr_ll a;
	
	memset(&a, 0, sizeof(a));
	
	s = socket(PF_PACKET, SOCK_DGRAM, ETH_P_IP);
	if (s < 0) {
		perror("socket");
		exit(-1);
	}

	printf("ser_num\trecv_time\t send_t\n");
	while (1) {
		unsigned char buffer[1400];
		int i;
		struct timeval now;
		gettimeofday(&now, NULL);
	
		i = recvfrom(s, buffer, 1400, 0, NULL, NULL);
		printf("%s\t%d.%d\t%s\n", buffer, now.tv_sec, now.tv_usec, buffer+8);
	}
}
I want to show the "buffer" on receiver side which is sending from server.
Could someone please help me how to do that?
Is my program to receive the RAW packets correct?
Do I need to get RAW packets from specified port on receiver? if yes, how?

Appreciate
 
Old 10-04-2010, 08:37 PM   #9
mehdiizadeh
LQ Newbie
 
Registered: Jun 2007
Posts: 9

Original Poster
Rep: Reputation: 0
I've realized that to receive the RAW packets, the following steps are needed to be done:

Quote:
1. Create RAW socket.
2. Bind socket to interface.
3. Start Sniffing the packets (recvfrom()).
4. Parse ethernet header.
5. Parse IP header.
6. Parse TCP header.
7. Parse Data.
To access the data, It is necessary to decode the data portion of the packet by removing ethernet-IP-TCP headers which are received in RAW packets.

Please look at my last post, the way i forward the received UDP packet to MAC dest address is correct?
do i need to add ethernet and IP headers before forwarding UDP packets?

Any suggestion?
Thanks
 
  


Reply



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
Send packets to yourself, out one interface and in another algol68 Linux - Networking 3 12-22-2008 02:02 PM
Send packets manually Ephracis Programming 4 04-02-2005 04:56 AM
unable to send packets cranium2004 Linux - Networking 2 02-05-2005 10:28 PM
How do you send packets in ASM? Qwirt Programming 4 11-13-2004 03:11 PM
recieve and send IP packets! Farhang Linux - Networking 1 07-25-2004 02:47 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:58 AM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration