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 (12 years, 1 month 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

# Content
1 /*
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 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "list.h"
27 #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 #include "conf.h"
38 #include "conf_class.h"
39
40
41 static void do_actual_trace(struct Client *, int, char *[]);
42 static void report_this_status(struct Client *, struct Client *, int);
43
44 static void
45 trace_get_dependent(unsigned int *const server,
46 unsigned int *const client, const struct Client *target_p)
47 {
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 /*
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 const char *tname = NULL;
68
69 if (parc > 1)
70 tname = parv[1];
71 else
72 tname = me.name;
73
74 sendto_one(source_p, form_str(RPL_ENDOFTRACE),
75 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 if ((ac2ptr = hash_find_client(tname)) == NULL)
117 {
118 DLINK_FOREACH(ptr, global_client_list.head)
119 {
120 ac2ptr = ptr->data;
121
122 if (!match(tname, ac2ptr->name))
123 break;
124 else
125 ac2ptr = NULL;
126 }
127 }
128
129 if (ac2ptr != NULL)
130 sendto_one(source_p, form_str(RPL_TRACELINK), from, to,
131 ircd_version, tname, ac2ptr->from->name);
132 else
133 sendto_one(source_p, form_str(RPL_TRACELINK), from, to,
134 ircd_version, tname, "ac2ptr_is_NULL!!");
135 return;
136 }
137
138 case HUNTED_ISME:
139 do_actual_trace(source_p, parc, parv);
140 break;
141 default:
142 return;
143 }
144 }
145
146 /*
147 ** ms_trace
148 ** parv[0] = sender prefix
149 ** parv[1] = servername
150 */
151 static void
152 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 if (HasUMode(source_p, UMODE_OPER))
159 mo_trace(client_p, source_p, parc, parv);
160 }
161
162 static void
163 do_actual_trace(struct Client *source_p, int parc, char *parv[])
164 {
165 struct Client *target_p = NULL;
166 int doall = 0;
167 int wilds, dow;
168 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 sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE,
188 "TRACE requested by %s (%s@%s) [%s]",
189 source_p->name, source_p->username,
190 source_p->host, source_p->servptr->name);
191
192 if (!match(tname, me.name))
193 doall = 1;
194 else if (!MyClient(source_p) && !strcmp(tname, me.id))
195 {
196 doall = 1;
197 tname = me.name;
198 }
199
200 wilds = !parv[1] || has_wildcards(tname);
201 dow = wilds || doall;
202
203 set_time();
204 if (!HasUMode(source_p, UMODE_OPER) || !dow) /* non-oper traces must be full nicks */
205 /* lets also do this for opers tracing nicks */
206 {
207 const char *name;
208 target_p = hash_find_client(tname);
209
210 if (target_p && IsClient(target_p))
211 {
212 name = get_client_name(target_p, HIDE_IP);
213
214 if (HasUMode(target_p, UMODE_OPER))
215 {
216 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
217 from, to, get_client_class(&target_p->localClient->confs), name,
218 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
219 CurrentTime - target_p->localClient->lasttime,
220 idle_time_get(source_p, target_p));
221 }
222 else
223 {
224 sendto_one(source_p,form_str(RPL_TRACEUSER),
225 from, to, get_client_class(&target_p->localClient->confs), name,
226 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
227 CurrentTime - target_p->localClient->lasttime,
228 idle_time_get(source_p, target_p));
229 }
230 }
231
232 sendto_one(source_p, form_str(RPL_ENDOFTRACE),
233 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 if (HasUMode(target_p, UMODE_INVISIBLE) && dow &&
243 !(MyConnect(source_p) && HasUMode(source_p, UMODE_OPER)) &&
244 !HasUMode(target_p, UMODE_OPER) && (target_p != source_p))
245 continue;
246 if (!doall && wilds && match(tname, target_p->name))
247 continue;
248 if (!dow && irccmp(tname, target_p->name))
249 continue;
250
251 report_this_status(source_p, target_p, dow);
252 }
253
254 DLINK_FOREACH(ptr, serv_list.head)
255 {
256 target_p = ptr->data;
257
258 if (!doall && wilds && match(tname, target_p->name))
259 continue;
260 if (!dow && irccmp(tname, target_p->name))
261 continue;
262
263 report_this_status(source_p, target_p, dow);
264 }
265
266 /* This section is to report the unknowns */
267 DLINK_FOREACH(ptr, unknown_list.head)
268 {
269 target_p = ptr->data;
270
271 if (!doall && wilds && match(tname, target_p->name))
272 continue;
273 if (!dow && irccmp(tname, target_p->name))
274 continue;
275
276 report_this_status(source_p, target_p, dow);
277 }
278
279 DLINK_FOREACH(ptr, class_get_list()->head)
280 {
281 const struct ClassItem *class = ptr->data;
282
283 if (class->ref_count > 0)
284 sendto_one(source_p, form_str(RPL_TRACECLASS),
285 from, to, class->name, class->ref_count);
286 }
287
288 sendto_one(source_p, form_str(RPL_ENDOFTRACE), from, to, tname);
289 }
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 static void
299 report_this_status(struct Client *source_p, struct Client *target_p, int dow)
300 {
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 class_name = get_client_class(&target_p->localClient->confs);
318
319 set_time();
320
321 switch (target_p->status)
322 {
323 case STAT_CONNECTING:
324 sendto_one(source_p, form_str(RPL_TRACECONNECTING),
325 from, to, class_name,
326 HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name);
327 break;
328 case STAT_HANDSHAKE:
329 sendto_one(source_p, form_str(RPL_TRACEHANDSHAKE),
330 from, to, class_name,
331 HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name);
332 break;
333 case STAT_ME:
334 break;
335 case STAT_UNKNOWN:
336 /* added time -Taner */
337 sendto_one(source_p, form_str(RPL_TRACEUNKNOWN),
338 from, to, class_name, name, target_p->sockhost,
339 CurrentTime - target_p->localClient->firsttime);
340 break;
341 case STAT_CLIENT:
342 /*
343 * Only opers see users if there is a wildcard
344 * but anyone can see all the opers.
345 */
346 if ((HasUMode(source_p, UMODE_OPER) &&
347 (MyClient(source_p) || !(dow && HasUMode(target_p, UMODE_INVISIBLE))))
348 || !dow || HasUMode(target_p, UMODE_OPER))
349 {
350 if (HasUMode(target_p, UMODE_ADMIN) && !ConfigFileEntry.hide_spoof_ips)
351 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
352 from, to, class_name, name,
353 HasUMode(source_p, UMODE_ADMIN) ? target_p->sockhost : "255.255.255.255",
354 CurrentTime - target_p->localClient->lasttime,
355 idle_time_get(source_p, target_p));
356
357 else if (HasUMode(target_p, UMODE_OPER))
358 {
359 if (ConfigFileEntry.hide_spoof_ips)
360 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
361 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 from, to, class_name, name,
368 MyOper(source_p) ? target_p->sockhost :
369 (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost),
370 CurrentTime - target_p->localClient->lasttime,
371 idle_time_get(source_p, target_p));
372 }
373 else
374 {
375 if (ConfigFileEntry.hide_spoof_ips)
376 sendto_one(source_p, form_str(RPL_TRACEUSER),
377 from, to, class_name, name,
378 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
379 CurrentTime - target_p->localClient->lasttime,
380 idle_time_get(source_p, target_p));
381 else
382 sendto_one(source_p, form_str(RPL_TRACEUSER),
383 from, to, class_name, name,
384 MyOper(source_p) ? target_p->sockhost :
385 (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost),
386 CurrentTime - target_p->localClient->lasttime,
387 idle_time_get(source_p, target_p));
388 }
389 }
390 break;
391 case STAT_SERVER:
392 {
393 unsigned int clients = 0;
394 unsigned int servers = 0;
395
396 trace_get_dependent(&servers, &clients, target_p);
397
398 if (!HasUMode(source_p, UMODE_ADMIN))
399 name = get_client_name(target_p, MASK_IP);
400
401 sendto_one(source_p, form_str(RPL_TRACESERVER),
402 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 break;
407 }
408
409 default: /* ...we actually shouldn't come here... --msa */
410 sendto_one(source_p, form_str(RPL_TRACENEWTYPE),
411 from, to, name);
412 break;
413 }
414 }
415
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