ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/modules/m_trace.c
Revision: 1011
Committed: Fri Sep 18 10:14:09 2009 UTC (16 years, 10 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/modules/m_trace.c
File size: 12641 byte(s)
Log Message:
- move list manipulation routines from tools.c to list.c
- mem_frob() goes to memory.c
- sort out redundant/unneeded header includes

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_trace.c: Traces a path to a client/server.
4     *
5     * Copyright (C) 2002 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26     #include "handlers.h"
27 michael 1011 #include "list.h"
28 adx 30 #include "hook.h"
29     #include "client.h"
30     #include "hash.h"
31     #include "common.h"
32     #include "irc_string.h"
33     #include "ircd.h"
34     #include "numeric.h"
35     #include "fdlist.h"
36     #include "s_bsd.h"
37     #include "s_serv.h"
38     #include "send.h"
39     #include "msg.h"
40     #include "parse.h"
41     #include "modules.h"
42     #include "s_conf.h"
43    
44 michael 889 static void m_trace(struct Client *, struct Client *, int, char *[]);
45     static void ms_trace(struct Client *, struct Client *, int, char *[]);
46     static void mo_trace(struct Client *, struct Client *, int, char *[]);
47     static void do_actual_trace(struct Client *, int, char *[]);
48 adx 30
49     struct Message trace_msgtab = {
50     "TRACE", 0, 0, 0, 0, MFLG_SLOW, 0,
51 michael 889 { m_unregistered, m_trace, ms_trace, m_ignore, mo_trace, m_ignore }
52 adx 30 };
53    
54     #ifndef STATIC_MODULES
55 knight 31 const char *_version = "$Revision$";
56 adx 30 static struct Callback *trace_cb;
57    
58     static void *
59     va_actual_trace(va_list args)
60     {
61     struct Client *source_p = va_arg(args, struct Client *);
62     int parc = va_arg(args, int);
63     char **parv = va_arg(args, char **);
64    
65     do_actual_trace(source_p, parc, parv);
66     return NULL;
67     }
68    
69     void
70     _modinit(void)
71     {
72     trace_cb = register_callback("doing_trace", va_actual_trace);
73     mod_add_cmd(&trace_msgtab);
74     }
75    
76     void
77     _moddeinit(void)
78     {
79     mod_del_cmd(&trace_msgtab);
80     uninstall_hook(trace_cb, va_actual_trace);
81     }
82     #endif
83    
84 michael 889 static void report_this_status(struct Client *, struct Client *, int);
85 adx 30
86 michael 889 static void
87     trace_get_dependent(int *const server,
88     int *const client, const struct Client *target_p)
89     {
90     const dlink_node *ptr = NULL;
91    
92     (*server)++;
93     (*client) += dlink_list_length(&target_p->serv->client_list);
94    
95     DLINK_FOREACH(ptr, target_p->serv->server_list.head)
96     trace_get_dependent(server, client, ptr->data);
97     }
98    
99 adx 30 /*
100     * m_trace()
101     *
102     * parv[0] = sender prefix
103     * parv[1] = target client/server to trace
104     */
105     static void
106     m_trace(struct Client *client_p, struct Client *source_p,
107     int parc, char *parv[])
108     {
109     const char *tname;
110    
111     if (parc > 1)
112     tname = parv[1];
113     else
114     tname = me.name;
115    
116     sendto_one(source_p, form_str(RPL_ENDOFTRACE),
117     me.name, source_p->name, tname);
118     }
119    
120    
121     /* mo_trace()
122     * parv[0] = sender prefix
123     * parv[1] = servername
124     */
125     static void
126     mo_trace(struct Client *client_p, struct Client *source_p,
127     int parc, char *parv[])
128     {
129     dlink_node *ptr;
130     const char *tname;
131     const char *from, *to;
132    
133     if (parc > 2)
134     if (hunt_server(client_p, source_p, ":%s TRACE %s :%s", 2, parc, parv))
135     return;
136    
137     if (parc > 1)
138     tname = parv[1];
139     else
140     tname = me.name;
141    
142     if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
143     {
144     from = me.id;
145     to = source_p->id;
146     }
147     else
148     {
149     from = me.name;
150     to = source_p->name;
151     }
152    
153     switch (hunt_server(client_p, source_p, ":%s TRACE :%s", 1, parc, parv))
154     {
155     case HUNTED_PASS: /* note: gets here only if parv[1] exists */
156     {
157     struct Client *ac2ptr = NULL;
158    
159     if ((ac2ptr = find_client(tname)) == NULL)
160     {
161     DLINK_FOREACH(ptr, global_client_list.head)
162     {
163     ac2ptr = ptr->data;
164    
165     if (match(tname, ac2ptr->name) || match(ac2ptr->name, tname))
166     break;
167     else
168     ac2ptr = NULL;
169     }
170     }
171    
172     if (ac2ptr != NULL)
173     sendto_one(source_p, form_str(RPL_TRACELINK), from, to,
174     ircd_version, tname, ac2ptr->from->name);
175     else
176     sendto_one(source_p, form_str(RPL_TRACELINK), from, to,
177     ircd_version, tname, "ac2ptr_is_NULL!!");
178     return;
179     }
180     case HUNTED_ISME:
181     #ifdef STATIC_MODULES
182     do_actual_trace(source_p, parc, parv);
183     #else
184     execute_callback(trace_cb, source_p, parc, parv);
185     #endif
186     break;
187     default:
188     return;
189     }
190     }
191    
192     static void
193 michael 889 do_actual_trace(struct Client *source_p, int parc, char *parv[])
194 adx 30 {
195     struct Client *target_p = NULL;
196     struct ConfItem *conf;
197     struct ClassItem *cltmp;
198     int doall = 0;
199 michael 889 int wilds, dow;
200 adx 30 dlink_node *ptr;
201     const char *from, *to, *tname;
202    
203     if (parc > 1)
204     tname = parv[1];
205     else
206     tname = me.name;
207    
208     if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
209     {
210     from = me.id;
211     to = source_p->id;
212     }
213     else
214     {
215     from = me.name;
216     to = source_p->name;
217     }
218    
219     if (match(tname, me.name))
220     doall = TRUE;
221     else if (!MyClient(source_p) && !strcmp(tname, me.id))
222     {
223     doall = TRUE;
224     tname = me.name;
225     }
226    
227     wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
228     dow = wilds || doall;
229    
230     set_time();
231     if (!IsOper(source_p) || !dow) /* non-oper traces must be full nicks */
232     /* lets also do this for opers tracing nicks */
233     {
234     const char *name;
235     const char *class_name;
236    
237     target_p = find_client(tname);
238    
239     if (target_p && IsClient(target_p))
240     {
241     name = get_client_name(target_p, HIDE_IP);
242     class_name = get_client_class(target_p);
243    
244     if (IsOper(target_p))
245     {
246     sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
247     from, to, class_name, name,
248 michael 891 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
249 adx 30 CurrentTime - target_p->lasttime,
250     CurrentTime - target_p->localClient->last);
251     }
252     else
253     {
254     sendto_one(source_p,form_str(RPL_TRACEUSER),
255     from, to, class_name, name,
256 michael 891 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
257 adx 30 CurrentTime - target_p->lasttime,
258     CurrentTime - target_p->localClient->last);
259     }
260     }
261    
262     sendto_one(source_p, form_str(RPL_ENDOFTRACE),
263     from, to, tname);
264     return;
265     }
266    
267     /* report all direct connections */
268     DLINK_FOREACH(ptr, local_client_list.head)
269     {
270     target_p = ptr->data;
271    
272     if (IsInvisible(target_p) && dow &&
273     !(MyConnect(source_p) && IsOper(source_p)) &&
274     !IsOper(target_p) && (target_p != source_p))
275     continue;
276     if (!doall && wilds && !match(tname, target_p->name))
277     continue;
278     if (!dow && irccmp(tname, target_p->name))
279     continue;
280    
281 michael 889 report_this_status(source_p, target_p, dow);
282 adx 30 }
283    
284     DLINK_FOREACH(ptr, serv_list.head)
285     {
286     target_p = ptr->data;
287    
288     if (!doall && wilds && !match(tname, target_p->name))
289     continue;
290     if (!dow && irccmp(tname, target_p->name))
291     continue;
292    
293 michael 889 report_this_status(source_p, target_p, dow);
294 adx 30 }
295    
296     /* This section is to report the unknowns */
297     DLINK_FOREACH(ptr, unknown_list.head)
298     {
299     target_p = ptr->data;
300    
301     if (!doall && wilds && !match(tname, target_p->name))
302     continue;
303     if (!dow && irccmp(tname, target_p->name))
304     continue;
305    
306 michael 889 report_this_status(source_p, target_p, dow);
307 adx 30 }
308    
309     DLINK_FOREACH(ptr, class_items.head)
310     {
311     conf = ptr->data;
312 michael 889 cltmp = map_to_conf(conf);
313    
314 adx 30 if (CurrUserCount(cltmp) > 0)
315     sendto_one(source_p, form_str(RPL_TRACECLASS),
316 michael 889 from, to, conf->name, CurrUserCount(cltmp));
317 adx 30 }
318    
319     sendto_one(source_p, form_str(RPL_ENDOFTRACE), from, to, tname);
320     }
321    
322     /*
323     ** ms_trace
324     ** parv[0] = sender prefix
325     ** parv[1] = servername
326     */
327     static void
328     ms_trace(struct Client *client_p, struct Client *source_p,
329     int parc, char *parv[])
330     {
331     if (hunt_server(client_p, source_p, ":%s TRACE %s :%s", 2, parc, parv))
332     return;
333    
334     if (IsOper(source_p))
335     mo_trace(client_p, source_p, parc, parv);
336     }
337    
338     /* report_this_status()
339     *
340     * inputs - pointer to client to report to
341     * - pointer to client to report about
342     * output - counter of number of hits
343     * side effects - NONE
344     */
345 michael 889 static void
346     report_this_status(struct Client *source_p, struct Client *target_p, int dow)
347 adx 30 {
348     const char *name;
349     const char *class_name;
350     const char *from, *to;
351    
352     if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
353     {
354     from = me.id;
355     to = source_p->id;
356     }
357     else
358     {
359     from = me.name;
360     to = source_p->name;
361     }
362    
363     name = get_client_name(target_p, HIDE_IP);
364     class_name = get_client_class(target_p);
365    
366     set_time();
367    
368 michael 889 switch (target_p->status)
369 adx 30 {
370     case STAT_CONNECTING:
371     sendto_one(source_p, form_str(RPL_TRACECONNECTING),
372     from, to, class_name,
373     IsOperAdmin(source_p) ? name : target_p->name);
374     break;
375     case STAT_HANDSHAKE:
376     sendto_one(source_p, form_str(RPL_TRACEHANDSHAKE),
377     from, to, class_name,
378     IsOperAdmin(source_p) ? name : target_p->name);
379     break;
380     case STAT_ME:
381     break;
382     case STAT_UNKNOWN:
383     /* added time -Taner */
384     sendto_one(source_p, form_str(RPL_TRACEUNKNOWN),
385 michael 891 from, to, class_name, name, target_p->sockhost,
386 adx 30 target_p->firsttime ? CurrentTime - target_p->firsttime : -1);
387     break;
388     case STAT_CLIENT:
389 michael 891 /*
390     * Only opers see users if there is a wildcard
391 adx 30 * but anyone can see all the opers.
392     */
393     if ((IsOper(source_p) &&
394     (MyClient(source_p) || !(dow && IsInvisible(target_p))))
395     || !dow || IsOper(target_p))
396     {
397     if (IsAdmin(target_p) && !ConfigFileEntry.hide_spoof_ips)
398     sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
399     from, to, class_name, name,
400 michael 891 IsOperAdmin(source_p) ? target_p->sockhost : "255.255.255.255",
401 adx 30 CurrentTime - target_p->lasttime,
402     CurrentTime - target_p->localClient->last);
403    
404     else if (IsOper(target_p))
405     {
406     if (ConfigFileEntry.hide_spoof_ips)
407     sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
408     from, to, class_name, name,
409 michael 891 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
410 adx 30 CurrentTime - target_p->lasttime,
411     CurrentTime - target_p->localClient->last);
412     else
413     sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
414     from, to, class_name, name,
415 michael 891 MyOper(source_p) ? target_p->sockhost :
416     (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost),
417 adx 30 CurrentTime - target_p->lasttime,
418     CurrentTime - target_p->localClient->last);
419     }
420     else
421     {
422     const char *format_str=NULL;
423     if (IsOper(source_p) && IsCaptured(target_p))
424     format_str = form_str(RPL_TRACECAPTURED);
425     else
426     format_str = form_str(RPL_TRACEUSER);
427    
428     if (ConfigFileEntry.hide_spoof_ips)
429     sendto_one(source_p, format_str,
430     from, to, class_name, name,
431 michael 891 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
432 adx 30 CurrentTime - target_p->lasttime,
433     CurrentTime - target_p->localClient->last);
434     else
435     sendto_one(source_p, format_str,
436     from, to, class_name, name,
437 michael 891 MyOper(source_p) ? target_p->sockhost :
438     (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost),
439 adx 30 CurrentTime - target_p->lasttime,
440     CurrentTime - target_p->localClient->last);
441     }
442     }
443     break;
444     case STAT_SERVER:
445 michael 889 {
446     int clients = 0;
447     int servers = 0;
448    
449     trace_get_dependent(&servers, &clients, target_p);
450    
451     if (!IsOperAdmin(source_p))
452 adx 30 name = get_client_name(target_p, MASK_IP);
453    
454     sendto_one(source_p, form_str(RPL_TRACESERVER),
455 michael 889 from, to, class_name, servers,
456     clients, name, *(target_p->serv->by) ?
457 adx 30 target_p->serv->by : "*", "*",
458     me.name, CurrentTime - target_p->lasttime);
459     break;
460 michael 889 }
461 adx 30
462     default: /* ...we actually shouldn't come here... --msa */
463     sendto_one(source_p, form_str(RPL_TRACENEWTYPE),
464 michael 889 from, to, name);
465 adx 30 break;
466     }
467     }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision