I am learning raw socket programming in linux Ubuntu but i have a problem. My udp packet is not shown in Wireshark. I suspect that its being dropped by my router because of a mistake I made.
here is my code.
#include<iostream>
#include<sys/ioctl.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<linux/ip.h>
#include<netdb.h>
#include<linux/udp.h>
struct pseudo_header {
uint32_t source_address;
uint32_t dest_address;
uint8_t placeholder;
uint8_t protocol;
uint16_t udp_length;
};
uint16_t calc_checksum(void* data, int len) {
uint16_t* ptr = (uint16_t*)data;
uint32_t sum = 0;
while (len > 1) {
sum += *ptr++;
len -= 2;
}
if (len == 1) {
sum += *(uint8_t*)ptr;
}
while(sum >> 16)
{
sum += (sum & 0xFFFF) + (sum >> 16) ;
}
return ~sum;
}
int main()
{
char sendbuff[28];
memset(sendbuff,0,28);
iphdr* ip_header = (iphdr*)sendbuff;
udphdr* udp_header = (udphdr*)(sendbuff + sizeof(iphdr));
pseudo_header psh;
ip_header->version = 4;
ip_header->ihl = 5;
ip_header->id = htons(5234);
ip_header->protocol = 17;
ip_header->tos = 0;
ip_header->tot_len = htons(28);
ip_header->frag_off = 0;
ip_header->ttl = 45;
inet_pton(AF_INET,"192.168.8.144",&ip_header->saddr);
inet_pton(AF_INET,"192.168.8.1",&ip_header->daddr);
ip_header->check = 0;
ip_header->check = calc_checksum(ip_header,sizeof(ip_header));
char checksum_data[20];
memset(checksum_data,0,20);
udp_header->source = htons(1134);
udp_header->dest = htons(12345);
udp_header->len = 8;
udp_header->check = 0;
psh.dest_address = ip_header->daddr;
psh.source_address = ip_header->saddr;
psh.placeholder = 0;
psh.udp_length = 8;
psh.protocol = ip_header->protocol;
memcpy(checksum_data,&psh,sizeof(pseudo_header));
memcpy(checksum_data + sizeof(pseudo_header), udp_header,8);
udp_header->check = calc_checksum(checksum_data,20);
int s = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
if(s == -1)
{
std::cout << "Could not open raw socket" << std::endl;
}
int optval = 1;
if(setsockopt(s,IPPROTO_IP,IP_HDRINCL,&optval,sizeof(optval)) == -1)
{
std::cout << "Could not set socket option!" << std::endl;
}
sockaddr_in dstinfo;
memset(&dstinfo,0,sizeof(dstinfo));
dstinfo.sin_addr.s_addr = ip_header->daddr;
dstinfo.sin_port = udp_header->dest;
dstinfo.sin_family = AF_INET;
if(sendto(s,sendbuff,28,0,(sockaddr*)&dstinfo,sizeof(dstinfo)) == -1)
{
std::cout << "Packet could not be sent!" << std::endl;
}
}
I have ran my program as root I suspect their is something wrong with my checksum calculation of the ip header or udp header. Please help.
8