LinuxQuestions.org
Share your knowledge at the LQ Wiki.
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-06-2009, 12:26 PM   #1
robtard
LQ Newbie
 
Registered: May 2009
Posts: 2

Rep: Reputation: 0
Wireshark UDP Packets Socket not set


Hi,

I have something strange going on. I am sending UDP encapsulated packets
from one machine to another. On the outbound machine the packets show up in wireshark as "UDP Checksum Incorrect" - I've read somewhere that this may be because wireshark views the packet before the NIC computes the checksum and puts it in the packet.

Either way, on the other end (receiving end) the machine getting the packets receives them on a 3G Sprint interface (ppp0), they show up in wireshark (without the UDP checksum incorrect) message. The packets are being sent to 8080 on that machine, where I have a socket bound to ppp0:8080 using the "recvfrom()" function. Strangely, the socket filedescriptor is not being set. Here is my code:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <net/if.h>

#include "monitorInterface.h"
#include "selectInterface.h"
#include "tunnelInterface.h"
//#include "capsulatePacket.h"

int handlePackets(int tunfd, struct tunnel *tun)
{
fd_set readSet;
int bufSize, maxfd, readfd, sockfd, rtn;
char *buffer = (char *)malloc(1600);
char buf[1600];

if( (readfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("read socket failed");
return -1;
}

struct sockaddr_in myAddr;
memset(&myAddr, 0, sizeof(struct sockaddr_in));
myAddr.sin_family = AF_INET;
myAddr.sin_port = htons((unsigned short)tun->localPort);
myAddr.sin_addr.s_addr = htonl(INADDR_ANY);

printf("Binding to local port: %d\n", ntohs(myAddr.sin_port) );

if( bind(readfd, (struct sockaddr *)&myAddr, sizeof(struct sockaddr_in)) < 0) {
perror("bind failed");
close(readfd);
return -1;
}


//TODO: this should be removed...shouldn't bind to device on read side if having multiple devices
char *bind_device = (char *)malloc(IFNAMSIZ);
strncpy(bind_device, "ppp0", IFNAMSIZ);
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));

if(setsockopt(readfd, SOL_SOCKET, SO_BINDTODEVICE, bind_device, IFNAMSIZ+1) < 0) {
perror("SO_BINDTODEVICE");
return -1;
}

//TODO: this duplicates code from interfaceBind() should remove from there
struct sockaddr_in destAddr;
memset(&destAddr, 0, sizeof(struct sockaddr_in));
destAddr.sin_family = AF_INET;
destAddr.sin_port = htons((unsigned short)tun->remotePort);
inet_pton(AF_INET, tun->remoteIP, &destAddr.sin_addr);

//struct sockaddr_in *test = tun->destAddr;
//printf("dest port: %d dest IP: %s\n", ntohs((unsigned short)(tun->destAddr).sin_port), (char *)inet_ntoa((tun->destAddr).sin_addr));
printf("stored port: %d stored IP: %s\n", (unsigned short)tun->remotePort, tun->remoteIP);


maxfd = (tunfd > readfd) ? tunfd : readfd;
sockfd = selectInterface(TEST);
printf("sockfd %d, readfd %d, tunfd %d maxfd %d\n", sockfd, readfd, tunfd, maxfd);

printf("output: ");

while(1)
{
//setup read descriptors
FD_ZERO(&readSet);
FD_SET(tunfd, &readSet);
FD_SET(readfd, &readSet);
//maxfd = (tunfd > readfd) ? tunfd : readfd;
//printf("maxfd %d\n", maxfd);
printf("$");

//TODO: how to know which fd is the max?
select((maxfd+1), &readSet, NULL, NULL, NULL);

if( FD_ISSET(tunfd, &readSet) ) {
printf("*");
//if( (bufSize = read(tunfd, buf, sizeof(buf))) < 0) {
if( (bufSize = read(tunfd, buffer, 1600)) < 0) {
perror("read packet error");
} else {
//select interface and send
if((sockfd = selectInterface(TEST)) < 0) {
printf("sockfd: %d\n", sockfd);
perror("selecting interface");
//return -1;
}
//TODO: this is a really big hack to overwrite the 2 bytes that come from ???
buffer += 2;
//if( (rtn = sendto(sockfd, buf, bufSize, 0, (struct sockaddr *)&destAddr, sizeof(struct sockaddr))) < 0) {
if( (rtn = sendto(sockfd, buffer, bufSize, 0, (struct sockaddr *)&destAddr, sizeof(struct sockaddr))) < 0) {
//perror("sendto failed");
printf("sendto failed: %s %d\n", (char *)strerror(errno), errno);
//printf("return value: %d, sockfd: %d\n", rtn, sockfd);
//return -1;
}
}
}

int fromlen = sizeof(struct sockaddr_in);
struct sockaddr_in * from = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));

//if packets returning from proxy
if( FD_ISSET(readfd, &readSet) ) {
printf("readfd set\n");
if( (bufSize = recvfrom(readfd, &buf[2], (sizeof(buf)-2), 0, (struct sockaddr *)from, &fromlen)) < 0) {
perror("recv failed");
} else {
//printf("sent to tunnet for denat\n");
buf[0] = 0x45;
buf[1] = 0x00;
if(write(tunfd, buf, (bufSize)) < 0) {
perror("writting to tunnel");
}
}
}

fflush(stdout);
}

return 1;
}


int main(int agrc, char *argv[])
{
struct tunnel *myTun = (struct tunnel *)malloc(sizeof(struct tunnel));

//scan interfaces
//char inbound_if[IFNAMSIZ] = "eth0";
interfaceScan(myTun);
interfacePrint(int_last);

//tunnel interface
int tunfd = tunnelInit(myTun);

//process packets
handlePackets(tunfd, myTun);

//clean up
interfaceCleanup(int_list, int_last);
return 1;
}
 
Old 05-07-2009, 06:42 AM   #2
amysaraantony
Member
 
Registered: Apr 2009
Posts: 42

Rep: Reputation: 16
Wow ... That's some scary code !
Sadly, I aint any good with network and sockets ... Sorry I couldnt be much help here ...


Debian

Last edited by amysaraantony; 05-15-2009 at 09:16 PM.
 
Old 08-07-2010, 03:41 PM   #3
asangau
LQ Newbie
 
Registered: Aug 2010
Posts: 1

Rep: Reputation: 0
Hello,

I too had a similar problem. I have an application that needs to send UDP over multiple network interfaces (ppp0, wlan0). But, the same, as described above was happening, i.e. wireshark was seeing the packet destined to the interface address, but not the select()/recvfrom() in the application which is bound to that interface. The outgoing packets from the application were going over the right interfaces.

I was using IPROUTE2 and iptables to forward outgoing packets generated from the approprite socket bound to the approprite interface at the network level. i.e.,
- iptables used to mark packets based on the approprite source address
- "ip rule" to forward marked packets to the approprite routing table
- "ip route" to create the different routing tables with entries to forward packets through the approprite interface

After trying many different things, including using Ubuntu 9.10 and 10.4, I found that, by removing the dependance on iptables and solely using IPROUTE2 for the network level routing for outgoing packets, the incomming packets became visible to the select()/recvfrom() of my application.

Unfortunately, I did not have time to investigate further. I had to move on to other issues.

Asanga Udugama
 
Old 10-27-2010, 06:45 PM   #4
Chief Sleepy Bear
LQ Newbie
 
Registered: Oct 2010
Posts: 1

Rep: Reputation: 0
Bad checksum's on outbound packets are normal

Don't mess with your system because you see checksum errors on outbound packets using wireshark. This is normal, and should be ignored.

When your code sends packets, you do not calculate the checksum. Also, the socket library does not calculate the checksum when it creates the udp packet header. This is because your network card or driver will compute the checksum for you. Network cards have gotten smarter, so some work is offloaded to the card.

If you really want to see what packets look like leaving your computer, then you can do what I do. I have a tiny micro ATX linux computer that has three gigabit network interfaces. (nothing special, just a normal computer with linux installed) I make a network bridge out of two interfaces. The third interface has the IP address configured like usual for a workstation. The bridge has no ip address, and is invisible to the network. I can use the bridge to observer packets, capture streams, and block network streams.

You have to get the cabling right. It seems easy to me, but I noticed people at work have trouble figuring out how to connect the parts.
 
  


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
How to capture packets using wireshark exl75 Linux - General 24 07-21-2007 03:10 AM
UDP: Short Packets: and UDP bad checksum: entries in dmesg minutes2memories Linux - Networking 2 02-26-2006 08:28 PM
what would happen if set the SO_SENDBUG for udp socket to 0? ringerxyz Programming 0 02-20-2005 03:16 AM
encapsulating TCP packets in UDP packets... yoshi95 Programming 3 06-03-2004 03:53 PM
How to receive UDP and ICMP packets, by one UDP socket(PMTUD) myself_rajat Linux - Networking 0 05-28-2004 06:43 AM

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

All times are GMT -5. The time now is 11:54 PM.

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