Skip to content

Instantly share code, notes, and snippets.

@Solution
Created October 7, 2011 20:25
Show Gist options
  • Save Solution/1271278 to your computer and use it in GitHub Desktop.
Save Solution/1271278 to your computer and use it in GitHub Desktop.
Playing with sockets
/*
* File: main.cpp
* Author: patrik
*
* Created on October 7, 2011, 12:14 PM
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sstream>
#include <iomanip>
using namespace std;
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
#define DNS_PORT 53
#define BUFFER_SIZE 8092
typedef struct{
uint m_id;
uint m_qr;
uint m_opcode;
uint m_aa;
uint m_tc;
uint m_rd;
uint m_ra;
uint m_qdCount;
uint m_anCount;
uint m_nsCount;
uint m_arCount;
string m_qName;
uint m_qType;
uint m_qClass;
} dnsPacket;
static const uint QR_MASK = 0x8000;
static const uint OPCODE_MASK = 0x7800;
static const uint AA_MASK = 0x0400;
static const uint TC_MASK = 0x0200;
static const uint RD_MASK = 0x0100;
static const uint RA_MASK = 0x8000;
static const uint RCODE_MASK = 0x000F;
static const uint HDR_OFFSET = 12;
int get16bits(const char*& buffer){
int value = static_cast<uchar> (buffer[0]);
value = value << 8;
value += static_cast<uchar> (buffer[1]);
buffer += 2;
return value;
}
string decode_qname(const char*& buffer)
{
string m_qName;
m_qName.clear();
int length = *buffer++;
while (length != 0) {
for (int i = 0; i < length; i++) {
char c = *buffer++;
m_qName.append(1, c);
}
length = *buffer++;
if (length != 0) m_qName.append(1,'.');
}
return m_qName;
}
dnsPacket decode(const char* buffer)
{
dnsPacket packet;
packet.m_id = get16bits(buffer);
uint fields = get16bits(buffer);
packet.m_qr = fields & QR_MASK;
packet.m_opcode = fields & OPCODE_MASK;
packet.m_aa = fields & AA_MASK;
packet.m_tc = fields & TC_MASK;
packet.m_rd = fields & RD_MASK;
packet.m_ra = fields & RA_MASK;
packet.m_qdCount = get16bits(buffer);
packet.m_anCount = get16bits(buffer);
packet.m_nsCount = get16bits(buffer);
packet.m_arCount = get16bits(buffer);
buffer += HDR_OFFSET;
packet.m_qName = decode_qname(buffer);
packet.m_qType = get16bits(buffer);
packet.m_qClass = get16bits(buffer);
return packet;
}
string queryAsString(dnsPacket packet)
{
ostringstream text;
text << "ID: " << showbase << hex << packet.m_id << endl << noshowbase;
text << "\tfields: [ QR: " << packet.m_qr << " opCode: " << packet.m_opcode << " ]" << endl;
text << "\tQDcount: " << packet.m_qdCount << endl;
text << "\tANcount: " << packet.m_anCount << endl;
text << "\tNScount: " << packet.m_nsCount << endl;
text << "\tARcount: " << packet.m_arCount << endl;
text << "QUERY {\t " << endl;
text << "\tQname: " << packet.m_qName << endl;
text << "\tQtype: " << packet.m_qType << endl;
text << "\tQclass: " << packet.m_qClass;
text << " }" << dec;
return text.str();
}
/*
*
*/
int main(int argc, char** argv)
{
int sockfd, newsockfd, portno; // int statements
socklen_t clilen; // length of socket
char buffer[BUFFER_SIZE]; // buffer
struct sockaddr_in serv_addr, cli_addr; // structures for socket address, for server and client
// try to create socket
if((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
perror("Cannot create socket");
exit(1);
}
// Server socket structure
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(DNS_PORT);
// Bind the socket
if(bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1)
{
perror("Cannot bind the socket");
exit(1);
}
do
{
// Do receive
clilen = sizeof(cli_addr);
int recvBytes;
if((recvBytes = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr*) &cli_addr, &clilen)) == -1)
{
perror("receive error: ");
exit(1);
}
string text = queryAsString(decode(buffer));
// Print the connection
cout << "Connection from: " << inet_ntoa(cli_addr.sin_addr) << endl;
cout << "DNS query: " << text << endl;
}while(true);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment