ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/modules/m_trace.c
Revision: 889
Committed: Thu Nov 1 12:59:05 2007 UTC (18 years, 8 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/modules/m_trace.c
File size: 12971 byte(s)
Log Message:
- Got rid of Serv.dep_users and Serv.dep_servers

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

Properties

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