#include #include #include #include #include #include #include #include #include #include #include #include #include #define socklen_t int #define IP_Header_Size sizeof(struct ip) #define UDP_Header_Size sizeof(struct udphdr) #define Data_Size strlen(DATA) #define DATA "Hello World!" #define Total_Size 40 // this needs to be set to the actual number, not more constants // use cout << IP_Header_Size+UDP_Header_Size+Data_Size << endl; // to figure it out #define Sender_IP "192.168.1.100" #define Sender_Port "0" #define Receiver_IP "192.168.1.100" #define Receiver_Port "0" #pragma mark - #pragma mark - #pragma mark - struct psuedohdr { struct in_addr source_address; struct in_addr dest_address; unsigned char place_holder; unsigned char protocol; unsigned short length; } psuedohdr; void setupSocket(void); void setupHeaders(void); unsigned short in_cksum(unsigned short *addr,int len); unsigned short trans_check(unsigned char proto, char *packet, int length, struct in_addr source_address, struct in_addr dest_address); int sockfd; char datapacket[Total_Size]; struct ip * IP_Header = (struct ip *) datapacket; struct udphdr * UDP_Header = (struct udphdr *) datapacket+IP_Header_Size; struct sockaddr_in remote; #pragma mark - #pragma mark - #pragma mark - main () { setupSocket(); setupHeaders(); strcpy(datapacket+IP_Header_Size+UDP_Header_Size, DATA); // copy data over to packet /*if (write(sockfd, datapacket, Total_Size) < 0) { perror("write"); exit(1); }*/ if(bind(sockfd,(struct sockaddr *)&remote,(socklen_t)sizeof(remote)) < 0 ) { perror("Bind"); exit(1); } if (write(sockfd, datapacket, Total_Size) < 0) { perror("write"); exit(1); } if (sendto(sockfd, datapacket, Total_Size, 0, (struct sockaddr *)&remote, sizeof(remote)) < 0) { perror("sendto"); exit(1); } } void setupSocket(void) { int yes=1; if( (sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_UDP)) < 0 ) { perror("sock"); exit(1); } if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) < 0) { perror("setsockopt"); exit(1); } if(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &yes,sizeof(yes)) < 0 ) { perror("setsockopt:"); exit(errno); } } void setupHeaders(void) { bzero(datapacket, Total_Size); struct in_addr saddr, daddr; unsigned int sport, dport; saddr.s_addr = inet_addr(Sender_IP); daddr.s_addr = inet_addr(Receiver_IP); sport = atoi(Sender_Port); dport = atoi(Receiver_Port); remote.sin_family = AF_INET; remote.sin_port = htons(dport); remote.sin_addr = daddr; UDP_Header->uh_sport=htons(sport); UDP_Header->uh_dport=htons(dport); UDP_Header->uh_ulen=htons(UDP_Header_Size+Data_Size); UDP_Header->uh_sum= trans_check(IPPROTO_UDP, (char *)UDP_Header, UDP_Header_Size, saddr, daddr); IP_Header->ip_hl = 5; IP_Header->ip_v = 4; IP_Header->ip_tos = 0; IP_Header->ip_len = htons(IP_Header_Size); IP_Header->ip_off = htons(IP_DF); IP_Header->ip_ttl = 255; IP_Header->ip_p = htons(17); IP_Header->ip_sum = htons((unsigned short)in_cksum((unsigned short *)IP_Header, IP_Header_Size)); IP_Header->ip_src.s_addr = inet_addr(Sender_IP); IP_Header->ip_dst.s_addr = inet_addr(Receiver_IP); } unsigned short in_cksum(unsigned short *addr,int len) { register int sum = 0; u_short answer = 0; register u_short *w = addr; register int nleft = len; /* * Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer); } unsigned short trans_check(unsigned char proto, char *packet, int length, struct in_addr source_address, struct in_addr dest_address) { char *psuedo_packet; unsigned short answer; psuedohdr.protocol = proto; psuedohdr.length = htons(length); psuedohdr.place_holder = 0; psuedohdr.source_address = source_address; psuedohdr.dest_address = dest_address; if((psuedo_packet = (char *)malloc(sizeof(psuedohdr) + length)) == NULL) { perror("malloc"); exit(1); } memcpy(psuedo_packet,&psuedohdr,sizeof(psuedohdr)); memcpy((psuedo_packet + sizeof(psuedohdr)), packet,length); answer = (unsigned short)in_cksum((unsigned short *)psuedo_packet, (length + sizeof(psuedohdr))); free(psuedo_packet); return answer; }