Previous Thread
Next Thread
Print Thread
Rate Thread
#17109 03/07/03 12:34 AM
Joined: Jun 2002
Posts: 207
Gollum Offline OP
Member
OP Offline
Member
Joined: Jun 2002
Posts: 207
i just began programming sockets in C. i decided for my first project to make a port scanner. everythign was working fine until i added the gethostbyname() fucntion to it. now everytime i run it i get a Segmentation Fault. I've tried to pinpoint it, but it's difficult. I only get the segmentation fault when I enter a valid ip address or domain. if the domain is invalid it sends back a custom error message. also if the user puts in the wrong number of arguments it calls a usage function. so i only have problems with the program when it doesn't encounter an error. In the code I set the first three variables to 5 to show that when the program runs, they are changed (or overwritten) to 0, 0, and 134519796 respectively. Also. I put a printf("hello"); followed by a fflush(stdout); followed by another printf("hello"); right after my declarations. when that happens, the only output is:
helloSegmentation Fault
does anyone know whats going on here??!

Output:
bash2.05a# ./pscan validdomain.com

sockfd: 0
n: 0
ret: 134519796

Segmentation fault

gdb output:
(gdb)run validdomain.com
Starting program: /home/gollum/projects/portscanner/pscan validdomain.com

sockfd: 0
n: 0
ret: 134519796


Program received signal SIGSEV, Segmentation fault.
__inet_aton (cp=0x2b6206d1 <Address 0x2b6206d1 out of bounds>, addr=0xbffff918) at inet_addr.c:130
130 inet_addr.c: No such file or directory.
in inet_addr.c
(gdb)bt
#0 __inet_aton (cp=0x2b6206d1 <Address 0x2b6206d1 out of bounds>, addr=0xbffff918) at inet_addr.c:130
#1 0x40102bd6 in inet_addr (cp=0x2b6206d1 <Address 0x2b6206d1 out of bounds>, addr=0xbffff918) at inet_addr.c:96
#2 0x0804887a in main (argc=2, argv=0xbffff9d4) at portscanner.c:74
#3 0x4003e17d in __libc_start_main (main=0x80486cc <main>, argc=2 ubp_av=0xbffff9d4, init-0x8048494 <_init>, fini=0x8048980 <_fini>, at ../sysdeps/generic/libc-start.c:129

CODE:([LT] is < and [GT] is >)
#include [LT]stdio.h[GT]
#include [LT]stdlib.h[GT]
#include [LT]errno.h[GT]
#include [LT]string.h[GT]
#include [LT]netdb.h[GT]
#include [LT]sys/types.h[GT]
#include [LT]netinet/in.h[GT]
#include [LT]sys/socket.h[GT]

void usage(char *s)
{
printf("\nGollum's First Port Scanner\nUsage: %s [LT]ip address[GT] [begin port] [end port]\n\n",s);
exit(1);
}

int main(int argc, char *argv[])
{
int sockfd = 5, n = 5, ret = 5;
struct hostent *host;
struct sockaddr_in targ_addr;
int openprt = 0, begport, endport, strdprt;

printf("\nsockfd: %d\nn: %d\nret: %d\n\n");
fflush(stdout);
if(argc [LT]= 1)
usage(argv[0]);
if(argc [GT] 4)
usage(argv[0]);


if((host = gethostbyname(argv[1])) == NULL){
printf("%s: unknown host: %s\n",argv[0],argv[1]);
exit(1);
}

if(argc == 4){
begport = atoi(argv[2]);
endport = atoi(argv[3]);
}
else{
begport = 1;
endport = 1024;
}


printf("Scanning [LT]%s[GT](%s) from port %d to %d...",host-[GT]h_name,inet_ntoa(*((struct in_addr *)host-[GT]h_addr)),begport,endport);

strdprt = endport - begport+1;

for(; begport [LT]= endport; begport++){


sockfd=socket(AF_INET,SOCK_STREAM,0);
bzero((char*)&targ_addr,sizeof(targ_addr));
targ_addr.sin_family=AF_INET;
targ_addr.sin_port=htons(begport);
targ_addr.sin_addr.s_addr = inet_addr(*((struct in_addr *)host-[GT]h_addr));
if((ret=connect(sockfd,(struct sockaddr *)&targ_addr,sizeof(targ_addr)))!=-1)
{
printf("\n--[GT] %d is Open",begport);
openprt++;}
for(n = 0; n [LT]= 12000000; n++);
}
printf("\nScan Finished\n");
if(openprt == 0){
printf("No open ports were detected on %s.\n",host);
}
else{
printf("The other %d ports scanned were closed.\n",strdprt-openprt);
}
close(sockfd);

return 0;
}


Unbodied unsouled unheard unseen
Let the gift be grown in the time to call our own
Truth is natural like a wind that blows
Follow the direction no matter where it goes
Let the truth blow like a hurricane through me
#17110 03/07/03 08:57 AM
Joined: Mar 2002
Posts: 1,273
DollarDNS Owner
Offline
DollarDNS Owner
Joined: Mar 2002
Posts: 1,273
gosh dang, well, I'm about to take a trip to see my mom. When I get there, I'll pour over your code and tell you what's wrong.

In the meantime, I have two C open source programs that use sockets that you can look at:

Uses both TCP and UDP to query DNS servers
http://serialcoders.sytes.net/Download/DNSLookup/DNS_v1.0.zip

Accepts and makes connections
http://serialcoders.sytes.net/Download/Router/TelnetRouter_v3.0.zip

Both use gethostbyname


Domain Registration, Hosting, Management
http://www.dollardns.net
#17111 03/08/03 03:43 AM
Joined: Mar 2002
Posts: 1,273
DollarDNS Owner
Offline
DollarDNS Owner
Joined: Mar 2002
Posts: 1,273
I believe this line is a crash alert:

printf("Scanning <%s>(%s) from port %d to %d...", host->h_name, inet_ntoa(*((struct in_addr*)host->h_addr)), begport, endport);

untested solution - to remove pointer dereferencing

printf("Scanning <%s>(%s) from port %d to %d...", host->h_name, inet_ntoa((struct in_addr*)host->h_addr), begport, endport);

and

targ_addr.sin_addr.s_addr = inet_addr(*((struct in_addr *)host->h_addr));

untested solution - correct invalid assignment of string pointer to long

memcpy(&targ_addr.sin_addr.s_addr, host.h_addr, 4);

since I AM at my mother's house, I don't have access to my C compiler and cannot test this for myself. But you can try my suggested changes.


Domain Registration, Hosting, Management
http://www.dollardns.net
#17112 03/09/03 10:00 PM
Joined: Jun 2002
Posts: 207
Gollum Offline OP
Member
OP Offline
Member
Joined: Jun 2002
Posts: 207
i tried them, with unsuccessful results. however, i found out why i was getting erroneous results for the 3 variables i searched for. i never added the varialbes at the end of the printf statement. i fixed that and they printed out fine. however, i'm stilling getting a segmentation fault. i've tried allocating memory for *host, but to no avail.//


Unbodied unsouled unheard unseen
Let the gift be grown in the time to call our own
Truth is natural like a wind that blows
Follow the direction no matter where it goes
Let the truth blow like a hurricane through me
#17113 03/10/03 10:03 AM
Joined: Mar 2002
Posts: 1,273
DollarDNS Owner
Offline
DollarDNS Owner
Joined: Mar 2002
Posts: 1,273
ok, I've started to test your code in LCC - for windows, so this is a bit difficult to test considering I think you're compiling under *nix.

BEFORE
printf("No open ports were detected on %s.\n",host);

AFTER
printf("No open ports were detected on %s.\n",host->h_name);

invalid argument type. host is a structure, not a string pointer.

BEFORE
close(sockfd);

AFTER
closesocket(sockfd);

This may be a windows specific function, but check to be sure you don't have a closesocket function.

BEFORE
targ_addr.sin_addr.s_addr = inet_addr(*((struct in_addr *)host-[GT]h_addr));

AFTER
memcpy(&targ_addr.sin_addr.s_addr, &host->h_addr, 4);

I noticed this error before, but I gave you the incorrect fix. I once again believe this to be your most likely crash error.

DELETED
bzero((char*)&targ_addr,sizeof(targ_addr));

I don't have bzero, so I deleted it. If by some wierd stroke of bad luck, this is your crash problem, then I suggest you delete it too for testing.

With all the above changes (plus the inclusion of one windows specific function to initialize sockets) I successfully ran the program on Win2k. Course, there's a bug where it didn't properly detect open ports, but I'll leave that up to you - unless you should ask help on that too. smile Once again, it could be a windows thing.


Domain Registration, Hosting, Management
http://www.dollardns.net
#17114 03/10/03 10:27 PM
Joined: Jun 2002
Posts: 207
Gollum Offline OP
Member
OP Offline
Member
Joined: Jun 2002
Posts: 207
ah, i got it to work. it had to do w/ one of the lines you wanted me to change:

targ_addr.sin_addr.s_addr = inet_addr(*((struct in_addr *)host- &gt h_addr));
it should have been:
targ_addr.sin_addr = *((struct in_addr *)host- &gt h_addr);

that fixed it. but, btw...do you multithread a port scanner in c just by creating more than one socket? i changed sockfd to sockfd[x] and changed my code accordingly. i'd like to know what your opinion is on creating an array of sockets. as of right now i have a for loop at the end and instead of 120000000 or whateve,r i have 150, and i have a total of 500 different sockets that i use.
i also changed bzero to memset.

targ_addr.sin_family=AF_INET;
targ_addr.sin_port=htons(onport);
targ_addr.sin_addr = *((struct in_addr *)host- &gt h_addr);
memset(&(targ_addr.sin_zero), '\0', 8);

if((ret=connect(sockfd[x],(struct sockaddr *)&targ_addr,sizeof(targ_addr)))!=-1)
{
printf("\n-- &gt %d is Open",onport);
openprt++;
}

for(n = 0; n &lt = 150; n++);
x++;
if(onport-begport &gt 500)
close(sockfd[x+1]);
if(x == 500)
x = 0;

at the end i have a for loop which closes all the sockets.
and yes, speaking of closeing sockets, i believe in *nix, sockets are still considered the same as files, hence sockfd is socket file descriptor. so you're actually opening a file descriptor, which you just close, so it's the same command.
this, to me, doesn't seem very efficient, but i don't know if there's another way to do this. i've checked online, but most of what i came up with has been how to do it with .NET, C#, or C++.//


Unbodied unsouled unheard unseen
Let the gift be grown in the time to call our own
Truth is natural like a wind that blows
Follow the direction no matter where it goes
Let the truth blow like a hurricane through me
#17115 03/11/03 08:14 AM
Joined: Mar 2002
Posts: 1,273
DollarDNS Owner
Offline
DollarDNS Owner
Joined: Mar 2002
Posts: 1,273
yes, I'm familiar with pseudo file handles, so I knew it would work with close(), I just like being as specific as possible in my code. So if there was a closesocket function, that's what I would opt to use. Basically, just see of closesocket works if you want and if it doesn't, continue to use close.

as for an array of sockets... that's not your problem. I'll give ya a technical terms and definitions concerning this point:

syncronous tcp scan
this is where you try to connect to a port one after another. Each time you successfully connect or fail, you close the socket and move to the next port. To coders, this is called BLOCKING sockets. In other words, the connect function will block (or not return) until the connection attempt failed or succeeded.

asyncronous tcp scan
the most popular technique for scanning. This involves a SINGLE thread, but many ports are being scanned at one time, asyncronously. To coders this is called NON-BLOCKING sockets. In other words, the connect function will return immediately, meanwhile the connection attempt is still in progress.

multithreaded
This is most popular for major server applications where the process spins off another thread for each client.


Now, the rules may be slightly different for *nix, but in windows, sockets are by default BLOCKING. If I were to create a tcp scanner in windows, I would set the socket to NON-BLOCKING and give the OS the handle to the window and message number I want associated with network events. Then I setup a loop to attempt to connect to a bunch of sockets, meanwhile, the OS will post a message to my window each time a connection attempt failed or succeeded.

Now for *nix, this is what I theorize. The general technique should be much the same. You need to set your sockets to NON-BLOCKING and give the OS a FUNCTION POINTER, so that it may notify your application whenever a connection attempt failed or succeeded. That function would be called a CALLBACK function by coders.

if that ISN'T how it works under *nix...

You MAY still have to set the sockets to NON-BLOCKING, then after you attempt to connect with a group of them, you start looping through them checking their current connection state. If they're still pending, ignore them. If they connected, close them, print. If they failed, close them. Whenever you decide that the loop has gone for long enough (timeout), then you close all and move to the next group of ports.


Domain Registration, Hosting, Management
http://www.dollardns.net
#17116 03/11/03 11:11 AM
Joined: Jun 2002
Posts: 207
Gollum Offline OP
Member
OP Offline
Member
Joined: Jun 2002
Posts: 207
ah, ok, i believe this would do the trick:

fcntl(sockfd, F_SETFL, O_NONBLOCK);
but...
"By setting a socket to non-blocking, you can effectively "poll" the socket for information. If you try to read from a non-blocking socket and there's no data there, it's not allowed to block--it will return -1 and errno will be set to EWOULDBLOCK.

Generally speaking, however, this type of polling is a bad idea. If you put your program in a busy-wait looking for data on the socket, you'll suck up CPU time like it was going out of style. A more elegant solution for checking to see if there's data waiting to be read comes in the following section on select()."
(thank god for beej.)

so i dunno...i assume i could use that, but i'll try both that and select and see which one works better.


Unbodied unsouled unheard unseen
Let the gift be grown in the time to call our own
Truth is natural like a wind that blows
Follow the direction no matter where it goes
Let the truth blow like a hurricane through me
#17117 03/11/03 12:25 PM
Joined: Jun 2002
Posts: 207
Gollum Offline OP
Member
OP Offline
Member
Joined: Jun 2002
Posts: 207
yea...after extensive search on non-blocking sockets...i've found the same conclusion almost everywhere...use select.//


Unbodied unsouled unheard unseen
Let the gift be grown in the time to call our own
Truth is natural like a wind that blows
Follow the direction no matter where it goes
Let the truth blow like a hurricane through me
#17118 03/11/03 03:55 PM
Joined: Mar 2002
Posts: 1,273
DollarDNS Owner
Offline
DollarDNS Owner
Joined: Mar 2002
Posts: 1,273
well isn't that fascinating. Seems select() is available for windows as well. I just may rewrite my socket code to use select instead of a window's message queue. Both are equivilent in efficiency, but why create a window when I don't need one? Good to know this.

For sure, I agree the second technique outlined above does sux0r big balls. Do NOT do things that way. If you do, be sure to release time every loop for the CPU to catch up on things. Under windows the function is called Sleep(). It puts the process on idle for the duration you specify.


Domain Registration, Hosting, Management
http://www.dollardns.net

Link Copied to Clipboard
Member Spotlight
Phatal
Phatal
Houston, TX
Posts: 298
Joined: April 2004
Forum Statistics
Forums41
Topics33,840
Posts68,858
Average Daily Posts1
Members2,176
Most Online3,253
Jan 13th, 2020
Latest Postings
Where and how do you torrent?
by danni75 - 03/01/24 05:58 AM
Animation,
by JohanKaariainen - 08/15/19 01:18 AM
Blackbeard.....
by Gremelin - 10/03/18 07:02 PM
my old account still exists!
by Crime - 08/10/18 02:47 PM
Okay WTF?
by HenryMiring - 09/27/17 01:45 AM
The History Thread...
by Gremelin - 08/11/17 12:11 PM
My friend NEEDS your HELP!
by Lena01 - 07/21/17 12:06 AM
I'm having fun with this guy.
by gabithompson730 - 07/20/17 01:50 AM
I want to upgrade my phone
by gabithompson730 - 07/20/17 01:49 AM
Doom 3
by Cyrez - 09/11/14 08:58 PM
Amazon Gift Card Generator/KeyGen?te
by Gecko666 - 08/22/14 09:21 AM
AIM scene 99-03
by lavos - 09/02/13 08:06 AM
Planetside 2
by Crime - 03/04/13 07:10 AM
Beta Testers Wanted
by Crime - 03/04/13 06:55 AM
Hello Everyone
by Gremelin - 02/12/12 06:01 PM
Tracfone ESN Generator
by Zanvin Green - 01/18/12 01:31 PM
Python 3 issue
by Testing - 12/17/11 09:28 PM
tracfone airtime
by Drache86 - 07/30/11 03:37 AM
Backdoors and the Infinite
by ZeroCoolStar - 07/10/11 03:52 AM
HackThisZIne #12 Releaseed!
by Pipat2 - 04/28/11 09:20 PM
gang wars? l33t-wars?
by Gremelin - 04/28/11 05:56 AM
Consolidate Forums
by diggin2deep - 04/21/11 10:02 AM
LAN Hacking Noob
by Gremelin - 03/12/11 12:42 AM
Top Posters
UGN Security 41,392
Gremelin 7,203
§intå× 3,255
SilentRage 1,273
Ice 1,146
pergesu 1,136
Infinite 1,041
jonconley 955
Girlie 908
unreal 860
Top Likes Received
Ghost 2
Cyrez 1
Girlie 1
unreal 1
Crime 1
Powered by UBB.threads™ PHP Forum Software 7.7.5