ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_trace.c
Revision: 1156
Committed: Tue Aug 9 20:29:20 2011 UTC (14 years, 11 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/m_trace.c
File size: 12339 byte(s)
Log Message:
- create ircd-hybrid-8 "branch"

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

Properties

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