ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_trace.c
Revision: 139
Committed: Sun Oct 16 06:01:13 2005 UTC (20 years, 9 months ago) by db
Content type: text/x-csrc
File size: 12670 byte(s)
Log Message:
- get rid of map_conf_item and unmap_conf_item
- Use an union in struct ConfItem, but only allocate memory needed


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

Properties

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