ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/pxys2-2.0.0/pxyscand/px/px.c
Revision: 3252
Committed: Wed Apr 2 20:41:43 2014 UTC (9 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 9932 byte(s)
Log Message:
- Imported pxys2-2.0.0

File Contents

# User Rev Content
1 michael 3252 /* Copyright (C) 2003,2004 Stephane Thiell
2     *
3     * This file is part of pxyscand/px (from pxys)
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * as published by the Free Software Foundation; either version 2
8     * of the License, or (at your option) any later version.
9     *
10     * This program is distributed in the hope that it will be useful,
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     * GNU General Public License for more details.
14     *
15     * You should have received a copy of the GNU General Public License
16     * along with this program; if not, write to the Free Software
17     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18     *
19     */
20     #define RCSID "$Id: px.c,v 1.2 2004/01/03 01:03:16 mbuna Exp $"
21    
22     #ifdef HAVE_CONFIG_H
23     #include "config.h"
24     #endif
25    
26     #define DEFAULT_SERVER "127.0.0.1"
27     #define DEFAULT_PORT 9601
28    
29     /* OPAS library header */
30     #include <opas/opas.h>
31    
32     /* PEAK library header */
33     #include <peak/peak.h>
34    
35     #include <assert.h>
36     #include <errno.h>
37     #include <stdio.h>
38     #include <signal.h>
39     #include <string.h>
40     #include <unistd.h>
41     #include <sys/types.h>
42     #include <sys/socket.h>
43     #include <netinet/in.h>
44     #include <arpa/inet.h>
45     #include <netdb.h>
46    
47     #define PERROR(e) do { perror(e); exit(1); } while(0)
48    
49     /* Callback prototypes */
50     static void opas_send_cb(const void *data, uint32_t length, void *uptr);
51     static void opas_reply_noproxy_cb(struct opas_msg_query *replyp,
52     void *context);
53     static void opas_reply_proxy_cb(struct opas_msg_reply_proxy *replyp,
54     void *context);
55     static void opas_reply_error_cb(struct opas_msg_reply_error *replyp,
56     void *context);
57     static void opas_reply6_noproxy_cb(struct opas_msg_query6 *replyp,
58     void *context);
59     static void opas_reply6_proxy_cb(struct opas_msg_reply6_proxy *replyp,
60     void *context);
61     static void opas_reply6_error_cb(struct opas_msg_reply6_error *replyp,
62     void *context);
63     static void opas_msg_user_cb(struct opas_msg_user_header *umsgp, void *data,
64     void *context);
65    
66     static uint16_t opas_port = DEFAULT_PORT;
67     static char *opas_server = DEFAULT_SERVER;
68     static opas_session_t session; /* Our current OPAS session */
69    
70     /* To open a new session, you need to define a few callbacks contained in
71     a struct opas_callbacks. You don't define callbacks you don't want.
72     */
73     static const struct opas_callbacks opas_cbs =
74     {
75     opas_send_cb, /* This one is called by the OPAS library when data needs to
76     * be send.
77     */
78    
79     /* IPv4 callbacks.
80     */
81     NULL, /* We don't plan to receive any queries, we are only a
82     * client! :)
83     */
84     opas_reply_noproxy_cb,
85     opas_reply_proxy_cb,
86     opas_reply_error_cb,
87    
88     /* IPv6 callbacks defined as an example, but pxyscand doesn't support IPv6
89     * scanning yet.
90     */
91     NULL, /* No ipv6 query wanted neither. */
92     opas_reply6_noproxy_cb,
93     opas_reply6_proxy_cb,
94     opas_reply6_error_cb,
95     opas_msg_user_cb
96     };
97    
98     static void
99     display_usage()
100     {
101     fprintf(stderr, "*** Usage: px [-v] [-s <server>] [-p <port>] <host>\n");
102     exit(1);
103     }
104    
105     static void
106     display_version()
107     {
108     fprintf(stderr, "*** px (%s/%s) - OPAS command line client\n",
109     PACKAGE, PACKAGE_VERSION);
110     fprintf(stderr, "*** Part of pxys v.2 - http://pxys.sf.net\n");
111     fprintf(stderr, "*** %s\n", RCSID);
112     exit(0);
113     }
114    
115     static int
116     parse_options(int *argc, char **argv[])
117     {
118     extern char *optarg;
119     extern int optind;
120     int c;
121    
122     while ((c = getopt(*argc, *argv, "p:s:v")) != -1)
123     {
124     switch (c)
125     {
126     case 'p':
127     opas_port = (uint16_t)atoi(optarg);
128     break;
129     case 's':
130     opas_server = strdup(optarg);
131     break;
132     case 'v':
133     display_version();
134     break;
135     case '?':
136     default:
137     display_usage();
138     break;
139     }
140     }
141    
142     *argc -= optind;
143     *argv += optind;
144     return 0;
145     }
146    
147     static void
148     stream_event_read(peak_stream s, opas_session_t session)
149     {
150     char buffer[1024];
151     int result;
152    
153     /* When we have something to read, we feed the OPAS library. If something
154     * interesting is available, the library call one of the previously defined
155     * callbacks.
156     */
157     result = peak_stream_read(s, buffer, sizeof(buffer));
158     if (opas_feed(session, buffer, result) == -1)
159     {
160     fprintf(stderr, "opas_feed() failure - bad reply from server\n");
161     exit(1);
162     }
163     }
164    
165     static void
166     stream_event(peak_stream s, int type, void *context)
167     {
168     char ipbuf[16];
169     struct sockaddr_in sin;
170     int len;
171    
172     switch (type)
173     {
174     case PEAK_STREAM_EVT_OPEN:
175     len = sizeof(sin);
176     peak_stream_get_address(s, (struct sockaddr *)&sin, &len);
177     if (!inet_ntop(AF_INET, &sin.sin_addr, ipbuf, sizeof(ipbuf)))
178     abort();
179     printf("Connected to %s.\n", ipbuf);
180     break;
181     case PEAK_STREAM_EVT_READ:
182     stream_event_read(s, session);
183     break;
184     case PEAK_STREAM_EVT_END:
185     fprintf(stderr, "Connection closed by server\n");
186     exit(1);
187     break;
188     case PEAK_STREAM_EVT_ERROR:
189     fprintf(stderr, "Socket stream error (server refused the"
190     " connection?)\n");
191     exit(1);
192     break;
193     default:
194     break;
195     }
196     }
197    
198     /* Called by the OPAS library when something needs to be send.
199     */
200     static void
201     opas_send_cb(const void *data, uint32_t length, void *uptr)
202     {
203     peak_stream_write_buffered((peak_stream)uptr, data, length);
204     }
205    
206     /* Called by the OPAS library when a negative reply arrives.
207     */
208     static void
209     opas_reply_noproxy_cb(struct opas_msg_query *replyp, void *context)
210     {
211     char ipbuf[16];
212    
213     printf("Got reply from OPAS server:\n");
214    
215     if (!inet_ntop(AF_INET, &replyp->addr, ipbuf, sizeof(ipbuf)))
216     abort();
217    
218     printf("NOPROXY : No proxy found on %s\n", ipbuf);
219    
220     exit(0); /* Don't bother. */
221     }
222    
223     /* Called by the OPAS library when a proxy has been found!
224     */
225     static void
226     opas_reply_proxy_cb(struct opas_msg_reply_proxy *replyp, void *context)
227     {
228     char ipbuf[16];
229    
230     printf("Got reply from OPAS server:\n");
231    
232     if (!inet_ntop(AF_INET, &replyp->addr, ipbuf, sizeof(ipbuf)))
233     abort();
234    
235     printf("PROXY : Proxy found on address %s\n", ipbuf);
236    
237     printf("%ld,type=%u,%s at port %u\n", replyp->timestamp,
238     replyp->proxy_type, replyp->proxy_descr, replyp->proxy_port);
239    
240     if (replyp->head & OPAS_FLAG_CACH)
241     printf("This proxy has been found in cache.\n");
242    
243     exit(0); /* Don't bother. */
244     }
245    
246     static void
247     opas_reply_error_cb(struct opas_msg_reply_error *replyp, void *context)
248     {
249     char ipbuf[16];
250    
251     printf("Got reply from OPAS server:\n");
252    
253     if (!inet_ntop(AF_INET, &replyp->addr, ipbuf, sizeof(ipbuf)))
254     abort();
255    
256     printf("ERROR : An error occured; unknown result for %s\n", ipbuf);
257    
258     switch (replyp->error)
259     {
260     case OPAS_ERROR_UNKNOWN:
261     printf(" Unknown OPAS error\n");
262     break;
263     case OPAS_ERROR_NETDOWN:
264     printf(" NETDOWN: network/host is down\n");
265     break;
266     case OPAS_ERROR_NETUNREACH:
267     printf(" NETUNREACH: network/host is not reachable\n");
268     break;
269     case 1000:
270     printf(" pxyscand resource error\n");
271     break;
272     default:
273     printf(" Really unknown error!\n");
274     break;
275     }
276    
277     exit(0);
278     }
279    
280     /* IPv6: Called by the OPAS library when a negative reply arrives.
281     */
282     static void
283     opas_reply6_noproxy_cb(struct opas_msg_query6 *replyp, void *context)
284     {
285     printf("opas_reply6_noproxy_cb\n");
286     exit(0);
287     }
288    
289     /* IPv6: Called by the OPAS library when a proxy has been found!
290     */
291     static void
292     opas_reply6_proxy_cb(struct opas_msg_reply6_proxy *replyp, void *context)
293     {
294     printf("opas_reply6_proxy_cb\n");
295     exit(0);
296     }
297    
298     /* IPv6: Called by the OPAS library when an host can't be scanned.
299     */
300     static void
301     opas_reply6_error_cb(struct opas_msg_reply6_error *replyp, void *context)
302     {
303     printf("opas_reply6_error_cb\n");
304     exit(0);
305     }
306    
307     /* User message over OPAS
308     */
309     static void
310     opas_msg_user_cb(struct opas_msg_user_header *umsgp, void *data,
311     void *context)
312     {
313     printf("OPAS msg user (not handled)\n");
314     }
315    
316     static void
317     create_tcp_session(struct in_addr *in)
318     {
319     struct sockaddr_in sin;
320     peak_stream s;
321     int err;
322    
323     memset(&sin, 0, sizeof(struct sockaddr_in));
324     sin.sin_family = AF_INET;
325     sin.sin_addr = *in;
326     sin.sin_port = htons(opas_port);
327    
328     s = peak_stream_socket_create((struct sockaddr *)&sin,
329     sizeof(struct sockaddr_in),
330     PEAK_STREAM_OPT_DEFAULT,
331     stream_event,
332     NULL);
333     assert(s != NULL);
334    
335     peak_stream_set_buffered(s, 1, 0, 8192, NULL);
336     err = peak_stream_connect(s);
337     if (err)
338     {
339     fprintf(stderr, "Can't connect to host\n");
340     exit(1);
341     }
342    
343     peak_stream_schedule(s, peak_task_self());
344    
345     session = opas_open_session(&opas_cbs, (void*)s);
346     assert(session != NULL);
347     }
348    
349    
350     static void
351     send_query(struct in_addr *in)
352     {
353     opas_query(session, in, 0xc0ffee);
354     }
355    
356     int
357     main(int argc, char *argv[])
358     {
359     struct hostent *h;
360     struct in_addr in_server, in_host;
361    
362     parse_options(&argc, &argv);
363     if (argc < 1)
364     display_usage();
365    
366     if ((h = gethostbyname(opas_server)) == NULL)
367     {
368     fprintf(stderr, "%s: unknown host\n", opas_server);
369     return 1;
370     }
371     memcpy((void *)&in_server.s_addr, *h->h_addr_list, h->h_length);
372    
373     if ((h = gethostbyname(argv[0])) == NULL)
374     {
375     fprintf(stderr, "%s: unknown host\n", argv[0]);
376     return 1;
377     }
378     memcpy((void *)&in_host.s_addr, *h->h_addr_list, h->h_length);
379    
380     create_tcp_session(&in_server);
381     send_query(&in_host);
382     peak_task_run(peak_task_self());
383     return 0;
384     }