1 // use rcb to compile: rcb portscanner.c
7 * License: LGPL 2.1+ with static linking exception
19 #include "../rocksock.h"
21 #pragma RcB2 LINK "-lpthread"
30 static pthread_mutex_t mutex
;
32 static void* scanHost(void* arg
) {
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)){
43 //printf("%s\n", soc->lasterror.errormsg);
47 rocksock_disconnect(soc
);
50 pthread_mutex_lock(&mutex
);
52 pthread_mutex_unlock(&mutex
);
56 int running(pthread_t
* t
, int max
) {
58 for (; i
<= max
; i
++) {
64 int joinThreads(pthread_t
* threads
, int max
) {
69 if (!pthread_join(threads
[i
], &exitstate
)) {
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};
86 pthread_attr_init(&attr
);
87 pthread_attr_getstacksize(&attr
, &stack
);
89 pthread_attr_setstacksize(&attr
, stack
);
91 pthread_mutex_init(&mutex
, NULL
);
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
);
100 if (!pthread_create(&threads
[x
], &attr
, scanHost
, &data
[x
])) {
107 joinThreads(threads
, x
);
110 joinThreads(threads
, x
);
112 pthread_attr_destroy(&attr
);
115 for (; i
< 255; i
++) {
116 if (data
[i
].status
> 0) dprintf(1, "%s\n", data
[i
].host
);
119 pthread_mutex_destroy(&mutex
);
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};
133 pthread_attr_init(&attr
);
134 pthread_attr_getstacksize(&attr
, &stack
);
136 pthread_attr_setstacksize(&attr
, stack
);
138 pthread_mutex_init(&mutex
, NULL
);
140 int currport
= sport
, i
;
141 while(done
< n_ports
) {
143 for(i
= 0; i
< maxthreads
; ++i
) {
144 volatile threaddata
* d
= &data
[i
];
146 if(currport
>= eport
) {
150 memset(d
, 0, sizeof *d
);
151 snprintf(d
->host
, sizeof(d
->host
), "%s", ip
);
152 d
->port
= currport
++;
154 pthread_create(&threads
[i
], &attr
, scanHost
, &data
[i
]);
156 if(d
->status
!= -1) {
157 pthread_join(threads
[i
], 0);
160 printf("port open: %d\n", d
->port
);
164 if(zero
== maxthreads
) break;
168 pthread_attr_destroy(&attr
);
169 pthread_mutex_destroy(&mutex
);
174 int main(int argc
, char** argv
) {
177 dprintf(2, "multithreaded portscanner\n"
179 "-subnet single port mode:\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",
189 char* ip
= argv
[1], *p
= ip
;
191 while(*p
) if(*(p
++) == '.') ++n
;
192 if(n
< 2 || n
> 3) goto syntax
;
193 int maxthreads
= atoi(argv
[3]);
195 int port
= atoi(argv
[2]);
196 scanRange(ip
, port
, maxthreads
);
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
);