LQ Newbie
Registered: May 2009
Posts: 2
Rep:
|
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;
}
|