examples/portscanner: quick hack to make it work on single host/portrange
[rofl0r-rocksock.git] / examples / portscanner.c
blob8dea4db259bf80107db32d1825b15bbca64a9b68
1 // use rcb to compile: rcb portscanner.c
3 /*
5 * author: rofl0r
7 * License: LGPL 2.1+ with static linking exception
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <pthread.h>
17 #include <errno.h>
18 #include <time.h>
19 #include "../rocksock.h"
21 #pragma RcB2 LINK "-lpthread"
23 typedef struct {
24 char host[16];
25 int port;
26 int status;
27 } threaddata;
29 static int done = 0;
30 static pthread_mutex_t mutex;
32 static void* scanHost(void* arg) {
33 threaddata* d = arg;
34 rocksock skt;
35 rocksock* soc = &skt;
36 rs_proxy proxies[1] = {0};
37 rocksock_init(soc, proxies);
38 rocksock_set_timeout(soc, 1500);
40 if (!rocksock_connect(soc, d->host, d->port, 0)){
41 d->status = 1;
42 } else {
43 //printf("%s\n", soc->lasterror.errormsg);
44 d->status = 0;
47 rocksock_disconnect(soc);
48 rocksock_clear(soc);
50 pthread_mutex_lock(&mutex);
51 done++;
52 pthread_mutex_unlock(&mutex);
53 return 0;
56 int running(pthread_t* t, int max) {
57 int res = 0, i = 0;
58 for (; i <= max; i++) {
59 if (t[i]) res++;
61 return res;
64 int joinThreads(pthread_t* threads, int max) {
65 void* exitstate;
66 int i = 0;
67 for(;i<max;i++) {
68 if (threads[i]) {
69 if (!pthread_join(threads[i], &exitstate)) {
70 threads[i] = 0;
71 free(exitstate);
75 return 0;
78 int scanRange(const char *ip, int port, int max_threads) {
80 int maxthreads = max_threads > 254 ? 254 : max_threads;
81 pthread_t threads[255] = {0};
82 threaddata data[255] = {0};
84 pthread_attr_t attr;
85 size_t stack;
86 pthread_attr_init(&attr);
87 pthread_attr_getstacksize(&attr, &stack);
88 stack = 32768;
89 pthread_attr_setstacksize(&attr, stack);
91 pthread_mutex_init(&mutex, NULL);
93 volatile int x = 1;
94 while(done < 254) {
95 while(x < 255 && running((pthread_t*) threads, x) < maxthreads) {
96 threaddata* d = &data[x];
97 snprintf(d->host, sizeof(d->host), "%s.%d", ip, x);
98 d->port = port;
99 d->status = -1;
100 if (!pthread_create(&threads[x], &attr, scanHost, &data[x])) {
101 x++;
103 else {
104 break;
107 joinThreads(threads, x);
110 joinThreads(threads, x);
112 pthread_attr_destroy(&attr);
114 int i = 0;
115 for (; i < 255; i++) {
116 if (data[i].status > 0) dprintf(1, "%s\n", data[i].host);
119 pthread_mutex_destroy(&mutex);
120 return 0;
124 int scanPortRange(const char *ip, int sport, int eport, int max_threads) {
126 int maxthreads = max_threads > 254 ? 254 : max_threads;
127 int n_ports = eport - sport;
128 pthread_t threads[255] = {0};
129 threaddata data[255] = {0};
131 pthread_attr_t attr;
132 size_t stack;
133 pthread_attr_init(&attr);
134 pthread_attr_getstacksize(&attr, &stack);
135 stack = 32768;
136 pthread_attr_setstacksize(&attr, stack);
138 pthread_mutex_init(&mutex, NULL);
140 int currport = sport, i;
141 while(done < n_ports) {
142 int zero = 0;
143 for(i = 0; i < maxthreads; ++i) {
144 volatile threaddata* d = &data[i];
145 if(!threads[i]) {
146 if(currport >= eport) {
147 ++zero;
148 continue;
150 memset(d, 0, sizeof *d);
151 snprintf(d->host, sizeof(d->host), "%s", ip);
152 d->port = currport++;
153 d->status = -1;
154 pthread_create(&threads[i], &attr, scanHost, &data[i]);
155 } else {
156 if(d->status != -1) {
157 pthread_join(threads[i], 0);
158 threads[i] = 0;
159 if(d->status == 1)
160 printf("port open: %d\n", d->port);
164 if(zero == maxthreads) break;
165 usleep(50);
168 pthread_attr_destroy(&attr);
169 pthread_mutex_destroy(&mutex);
170 return 0;
174 int main(int argc, char** argv) {
175 if (argc < 4) {
176 syntax:;
177 dprintf(2, "multithreaded portscanner\n"
178 "invalid syntax\n\n"
179 "-subnet single port mode:\n"
180 "%s 127.0.0 22 16\n"
181 "subnetA port maxthreads\n\n"
182 "-single host multi-port mode:\n"
183 "%s 127.0.0.1 portlist 16\n"
184 "ip portlist maxthreads\n"
185 "portlist specified as start-end in decimals\n",
186 argv[0], argv[0]);
187 return 1;
189 char* ip = argv[1], *p = ip;
190 int n = 0;
191 while(*p) if(*(p++) == '.') ++n;
192 if(n < 2 || n > 3) goto syntax;
193 int maxthreads = atoi(argv[3]);
194 if(n == 2) {
195 int port = atoi(argv[2]);
196 scanRange(ip, port, maxthreads);
197 return 0;
199 int startport = atoi(argv[2]);
200 if(!(p = strchr(argv[2], '-'))) goto syntax;
201 int endport = atoi(++p);
202 return scanPortRange(ip, startport, endport, maxthreads);