LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 01-31-2007, 11:52 AM   #1
wee-face
LQ Newbie
 
Registered: Jan 2007
Posts: 17

Rep: Reputation: 0
raw sockets in c


Hello everyone.

I'm planning to create a port scanner in c, i want it to
be able to do a half-open SYN scan to determine wether
or not the port is open, it seems fine, the code
compiles and runs on redhat linux 9.1.

Like i said it runs, but doesn't work, i can read
packets from a raw socket without a problem, but i
can't seem to write a packet to one.

I've ran my program along with tcpdump and was able to
see that no packets are being sent out, i can't see
what's wrong with it, sorry about the state of the
main() function, it's not very robust right now, i'm
trying to concentrate more on the meat of the program
before i worry about command line arguments etc.

The real concern is the inject_tcp_pkt() function,
any help will be appreciated, thanks.

#define __USE_BSD
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>

#define __FAVOR_BSD
#include <unistd.h>
#include <netinet/tcp.h>

#include <arpa/inet.h>

#define IP_HDR_SIZE (sizeof(struct ip))
#define TCP_HDR_SIZE (sizeof(struct tcphdr))
#define TCP_PKT_SIZE (sizeof(struct ip) + sizeof(struct tcphdr))

unsigned short chksum(unsigned short *, int);
int build_ip_pkt(char *, const char *, const char *);
int build_tcp_pkt(char *, short, short, unsigned char);
int inject_tcp_pkt(char *, const char *, short);
int grab_tcp_pkt(const char *, short, unsigned char, int);

unsigned short
ip_chksum(pkt, nwords)
unsigned short *pkt;
int nwords;
{

unsigned long sum;

for (sum = 0; nwords > 0; nwords--)
sum += *pkt++;

sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);

return ~sum;

}

int
build_ip_pkt(pkt, src_ip, dst_ip)
char *pkt;
const char *src_ip;
const char *dst_ip;
{

struct ip *ip_h = (struct ip *) pkt;

struct in_addr local;
struct in_addr remote;

inet_aton(src_ip, &local);
inet_aton(dst_ip, &remote);

ip_h -> ip_hl = 20;
ip_h -> ip_v = 4;
ip_h -> ip_tos = 0;
ip_h -> ip_len = TCP_PKT_SIZE;
ip_h -> ip_id = htonl(54321);
ip_h -> ip_off = 0;
ip_h -> ip_ttl = 255;
ip_h -> ip_p = IPPROTO_TCP;
ip_h -> ip_sum = 0;
ip_h -> ip_src.s_addr = local.s_addr;
ip_h -> ip_dst.s_addr = remote.s_addr;

}

int
build_tcp_pkt(pkt, src_port, dst_port, flags)
char *pkt;
short src_port;
short dst_port;
unsigned char flags;
{

struct ip *ip_h = (struct ip *) pkt;
struct tcphdr *tcp_h = (struct tcphdr *) (pkt + IP_HDR_SIZE);

tcp_h -> th_sport = htons(src_port);
tcp_h -> th_dport = htons(dst_port);
tcp_h -> th_seq = random();
tcp_h -> th_ack = 0;
tcp_h -> th_x2 = 0;
tcp_h -> th_off = 0;
tcp_h -> th_flags = flags;
tcp_h -> th_win = htons(65535);
tcp_h -> th_sum = 0;
tcp_h -> th_urp = 0;

ip_h -> ip_sum = ip_chksum((unsigned short *)pkt, ip_h -> ip_len >> 1);

}

/* the offending function
*/
int
inject_tcp_pkt(pkt, host, port)
char *pkt;
const char *host;
short port;
{

struct sockaddr_in remote;

int sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
int on = 1;

remote.sin_family = AF_INET;
remote.sin_port = htons(port);
inet_aton(host, &remote.sin_addr);
memset(remote.sin_zero, '\0', 8);

if (sock < 0)
return -1;

if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(int)) < 0)
return -2;

/* this is the problem right here
*/
if (sendto(sock, pkt, TCP_PKT_SIZE, 0, (struct sockaddr *)&remote, sizeof(struct sockaddr_in)) < 0)
return -3;

close(sock);

return 0;

}

int
grab_tcp_pkt(host, port, flags, nreads)
const char *host;
short port;
unsigned char flags;
int nreads;
{

char pkt[TCP_PKT_SIZE];

struct ip *ip_h = (struct ip *) pkt;
struct tcphdr *tcp_h = (struct tcphdr *) &pkt[IP_HDR_SIZE];

int sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
int reads = 0;

fd_set master;
fd_set tmp;
struct timeval tv;

FD_ZERO(&master);
FD_ZERO(&tmp);

if (sock < 0)
return -1;

FD_SET(sock, &master);

while (1) {
tmp = master;
tv.tv_sec = 0;
tv.tv_usec = 250;
if (select((sock + 1), &tmp, NULL, NULL, &tv) < 0)
return -2;

if (FD_ISSET(sock, &tmp)) {
memset(pkt, '\0', TCP_PKT_SIZE);

if (read(sock, pkt, TCP_PKT_SIZE) < 0)
return -3;

if (strcmp(inet_ntoa(ip_h -> ip_src), host) == 0) {
if (htons(tcp_h -> th_sport) == port) {
if (tcp_h -> th_flags == flags)
return 1;
else
return 0;
}
}
}

if (nreads > 0) {
if (++reads >= nreads)
break;
}
}

return 0;

}

int
main(argc, argv)
int argc;
char **argv;
{

char pkt[TCP_PKT_SIZE];
/* i've hard coded this stuff until i get
* inject_tcp_pkt() to work
*/
const char *localhost = "127.0.0.1";
const char *remotehost = "127.0.0.1"; /* the host to scan */
short localport = 12345;
short remoteport = 25; /* the port to scan */

int r;

memset(pkt, '\0', TCP_PKT_SIZE);
build_ip_pkt(pkt, localhost, remotehost);
build_tcp_pkt(pkt, localport, remoteport, TH_SYN);

/* once the packet is built, pass it to
* inject_tcp_pkt()
*/
inject_tcp_pkt(pkt, remotehost, remoteport);

/* grab_tcp_pkt() should read packets until
* it finds one from the remote host, from
* the remoteport (the port we're scanning)
* and checks to see if (TH_SYN and TH_ACK
* are set, if so it returns 1, otherwise
* it returns 0
*/
r = grab_tcp_pkt(remotehost, remoteport, (TH_SYN | TH_ACK), 500);

if (r == -1)
fprintf(stderr, "Error\n");
else if (r == 0)
fprintf(stderr, "Port closed\n");
else {
fprintf(stderr, "Port open\n");
}
exit(EXIT_SUCCESS);

}

Last edited by wee-face; 01-31-2007 at 11:53 AM.
 
Old 02-01-2007, 09:35 AM   #2
phoenix_benu
LQ Newbie
 
Registered: Jan 2007
Location: Croatia
Distribution: Debian, Suse, Mandrake (on old computer)
Posts: 9

Rep: Reputation: 0
Hi!

You can study nmap sources, mentioned technique is implemented there:

http://insecure.org/nmap/p51-11.html

Hope this helps.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Raw Sockets Srikanth0210 Programming 2 12-05-2005 03:22 AM
Pblm in Raw Sockets fpfernando Linux - Software 1 10-08-2005 01:04 AM
raw sockets and C wrongman Programming 3 05-04-2004 02:17 PM
can I use mmap with raw sockets? kanth Programming 2 02-28-2004 12:42 PM
raw sockets BashTin Programming 1 06-07-2003 06:34 AM


All times are GMT -5. The time now is 05:15 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration