ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_trace.c
Revision: 741
Committed: Sun Jul 23 13:49:20 2006 UTC (19 years, 1 month ago) by adx
Content type: text/x-csrc
File size: 12154 byte(s)
Log Message:
+ removed s_conf.h and superseded parts of s_conf.c

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

Properties

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