hello NG!
my program is to send udp messages (broadcast) for server-testing purposes.
[the server is working fine]
i am totally new to network programming and so i ran into some problems.
when i start my program my firewall does not ask for permission (so i guess
its not sending data)
would be great if someone of you could point me to my mistake (possibly show
me how to fix?)
thanks in advance
ludwig moser
here is my code
[udp.cpp]
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in_systm.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<netinet/udp.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<unistd.h> // sleep
#include<stdlib.h> // atoi
//#define MAXFILESIZE 65500
#define targetPort 1234
#define sourcePort 4123
#include "protocolHeaders.h"
struct sockaddr sa;
struct package
{
struct ipheader iph;
struct udpheader udph;
char datagram[4096];
void init()
{
memset (datagram, 0, 4096); /* zero out the buffer */
}
void setDatagram(char* data)
{
init();
memcpy(&datagram, data, sizeof(data));
}
};
unsigned short csum (unsigned short *buf, int nwords) /* this function
generates header checksums */
{
unsigned long sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
main(int argc,char **argv)
{
int fd;
int x=1;
struct sockaddr_in *p;
struct hostent *he;
int numpackets;
/************************************************** ****************************/
char datatosend[4096];
memset (datatosend, 0, 4096); /* zero out the buffer */
sprintf(datatosend, "something to send here %s", "yadda");
/************************************************** ****************************/
package data;
//data.init(); // zerofill the data part
data.setDatagram(bf2ServerInfos);
data.iph.ip_hl = 4;
data.iph.ip_v = 4;
data.iph.ip_tos = 0;
data.iph.ip_len = sizeof (struct ipheader) + sizeof (struct udpheader)
+sizeof(data.datagram); /* payload */
data.iph.ip_id = 1;
data.iph.ip_off = 0;
data.iph.ip_ttl = 255;
data.iph.ip_p = 17; // udp
data.iph.ip_sum = 0; // fill that later
data.iph.ip_src = inet_addr ("192.168.1.2");//localhost
data.iph.ip_dst = inet_addr ("192.168.1.255");// target
data.udph.uh_sport = htons (sourcePort); /* arbitrary port */
data.udph.uh_dport = htons (targetPort);
data.udph.uh_len = data.iph.ip_len;/* in a SYN packet, the sequence is a
random */
data.udph.uh_check = 0;/* if you set a checksum to zero, your kernel's IP
stack
should fill in the correct checksum during transmission */
data.iph.ip_sum = csum ((unsigned short *)data.datagram, data.iph.ip_len
>> 1);
if(argc!=4)
{
fprintf(stderr,"usage: %s sourcename destinationname numpackets\n",*argv);
return 1;
};
numpackets = atoi(argv[3]);
p=(struct sockaddr_in*)&sa;
p->sin_family=AF_INET;
if((fd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))== -1)
{
perror("socket");
return 1;
};
#ifdef IP_HDRINCL
fprintf(stderr,"\nWe have IP_HDRINCL \n\n");
if (setsockopt(fd,IPPROTO_IP,IP_HDRINCL,(char*)&x,siz eof(x))<0)
{
perror("setsockopt IP_HDRINCL");
return 1;
};
#else
fprintf(stderr,"\nWe don't have IP_HDRINCL \n\n");
#endif
printf("\nSending packages\n\n");
if (numpackets == -1)
{
numpackets = 99999;
}
struct sockaddr_in sin; /*
the sockaddr_in containing the dest. address is
used in sendto()
to determine the datagrams path
*/
sin.sin_family = AF_INET;
sin.sin_port = htons (sourcePort); /*
you byte-order >1byte header values to network
byte order (not
needed on big endian machines)
*/
sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
for(x=0;x<numpackets;x++)
{
sleep(1); // wait a sec till next send
if (sendto (fd, /* our socket */
data.datagram, /* the buffer containing headers and data */
data.iph.ip_len, /* total length of our datagram */
0, /* routing flags, normally always 0 */
(struct sockaddr *) &sin, /* socket addr, just like in */
sizeof (sin)) < 0); /* a normal send() */
/*
if((sendto(fd,&data,sizeof(data),0,(struct sockaddr*)p,sizeof(struct
sockaddr)))== -1)
{
perror("sendto");
return 1;
};
*/
//printf("%d ",x);
}
}
[/udp.cpp]
[protocolHeaders.h]
struct udpheader {
unsigned short int uh_sport; // Source Port
unsigned short int uh_dport; // Destination Port
unsigned short int uh_len; // udp header length
unsigned short int uh_check; // Checksum
}; /* total udp header length: 8 bytes (=64 bits) */
struct ipheader {
unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4 bits */
unsigned char ip_tos; //Type of Service
//These are rarely used. If one or more of these bits are set, they
indicate how routers should handle this packet.
unsigned short int ip_len; //Total length of packet
//What it sais: the total lengt of the packet, including this header and
including the data sent.
unsigned short int ip_id; //Identification
//A number identifiing this packet. Numbering packets is usefull when
fragmenting packets. See Fragmentation Offset.
unsigned short int ip_off; //Fragmentation Offset.
//If the total lengt is to large for a network to handle, it is divided
into smaller packets. These packets all have the same identification number.
If, for example, a packet 150 bytes large is send, but the network can only
handle packets with a maximum size of 100 bytes, the original packet is
fragmented in two others: the first will be 100 bytes large and will have a
fragmentation offset of 0 (first fragment). The second will be 50 bytes
long, and will have an offset of 50. Furthermore, it will have set its third
Flag, telling the receiver this is the last fragment of the packet. Now, the
receiver can completely reconstruct the original packet.
unsigned char ip_ttl; //Time to Live
//This is used to make sure no packet will wander through the internet for
eternity. Each router that handles this packet, will deduct at least 1 from
the Time to Live value. If a router receives a packet with a TTL of 1 or 0,
it will discard the package, and send a message to the source indicating
that the TTL-value has reached zero. This message is used by traceroute
programs: If you send out a packet to a destination, but you deliberately
set the TTL-value within the packet too small, one of the routers between
you and the destination will give you a reply. By adding 1 to the TTL and
resending the packet, the next router on the way will send you such a
message. This way, you can get messages (and thus identify) from all routers
between you and the destination.
unsigned char ip_p; //Protocol
//The protocol used in the packet. Typically 06 for TCP or 17 for UDP.
unsigned short int ip_sum; //Header Checksum
//Before sending, the sender calculates a checksum using date from this
packet. The receiver calculates this checksum again - if the value was
changed, the receiver can tell that the packet was damaged during transit.
unsigned int ip_src; //Source
//The IP-address of the sender of this packet.
unsigned int ip_dst; //Destination
//The IP-address of the intended receiver.
}; /* total ip header length: 20 bytes (=160 bits) */
[/protocolHeaders.h]