ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_trace.c
Revision: 2359
Committed: Thu Jul 4 21:03:19 2013 UTC (13 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 12598 byte(s)
Log Message:
- m_trace.c:report_this_status(): XXX solved. x->localClient->firsttime can't
  ever be zero

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

Properties

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