ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/modules/m_trace.c
Revision: 1121
Committed: Sun Jan 9 11:03:03 2011 UTC (15 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 12502 byte(s)
Log Message:
- removed all instances of STATIC_MODULES since we don't have
  static modules anymore
- removed m_mkpasswd module from contrib

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

Properties

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