ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_trace.c
Revision: 4967
Committed: Mon Dec 1 14:34:29 2014 UTC (10 years, 8 months ago) by michael
Content type: text/x-csrc
File size: 9735 byte(s)
Log Message:
- general::hide_spoof_ips is now deprecated

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2820 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 2820 * Copyright (c) 1997-2014 ircd-hybrid development team
5 adx 30 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 adx 30 * USA
20     */
21    
22 michael 2820 /*! \file m_trace.c
23     * \brief Includes required functions for processing the TRACE command.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 michael 1011 #include "list.h"
29 adx 30 #include "client.h"
30     #include "hash.h"
31     #include "irc_string.h"
32     #include "ircd.h"
33     #include "numeric.h"
34 michael 3347 #include "server.h"
35 adx 30 #include "send.h"
36     #include "parse.h"
37     #include "modules.h"
38 michael 1309 #include "conf.h"
39 michael 1632 #include "conf_class.h"
40 adx 30
41 michael 1230
42 michael 889 static void do_actual_trace(struct Client *, int, char *[]);
43     static void report_this_status(struct Client *, struct Client *, int);
44 adx 30
45 michael 889 static void
46 michael 2262 trace_get_dependent(unsigned int *const server,
47     unsigned int *const client, const struct Client *target_p)
48 michael 889 {
49 michael 4815 const dlink_node *node = NULL;
50 michael 889
51     (*server)++;
52     (*client) += dlink_list_length(&target_p->serv->client_list);
53    
54 michael 4815 DLINK_FOREACH(node, target_p->serv->server_list.head)
55     trace_get_dependent(server, client, node->data);
56 michael 889 }
57    
58 adx 30 /*
59     * m_trace()
60     *
61 michael 3096 * parv[0] = command
62 adx 30 * parv[1] = target client/server to trace
63     */
64 michael 2820 static int
65 michael 3156 m_trace(struct Client *source_p, int parc, char *parv[])
66 adx 30 {
67 michael 4815 const char *name = NULL;
68 adx 30
69     if (parc > 1)
70 michael 4815 name = parv[1];
71 adx 30 else
72 michael 4815 name = me.name;
73 adx 30
74 michael 4815 sendto_one_numeric(source_p, &me, RPL_ENDOFTRACE, name);
75 michael 2820 return 0;
76 adx 30 }
77    
78     /* mo_trace()
79 michael 3096 * parv[0] = command
80 adx 30 * parv[1] = servername
81     */
82 michael 2820 static int
83 michael 3156 mo_trace(struct Client *source_p, int parc, char *parv[])
84 adx 30 {
85 michael 4815 dlink_node *node = NULL;
86     const char *name = NULL;
87 adx 30
88     if (parc > 2)
89 michael 3156 if (hunt_server(source_p, ":%s TRACE %s :%s", 2, parc, parv) != HUNTED_ISME)
90 michael 2820 return 0;
91 adx 30
92     if (parc > 1)
93 michael 4815 name = parv[1];
94 adx 30 else
95 michael 4815 name = me.name;
96 adx 30
97 michael 3156 switch (hunt_server(source_p, ":%s TRACE :%s", 1, parc, parv))
98 adx 30 {
99     case HUNTED_PASS: /* note: gets here only if parv[1] exists */
100     {
101     struct Client *ac2ptr = NULL;
102    
103 michael 4815 if ((ac2ptr = hash_find_client(name)) == NULL)
104 adx 30 {
105 michael 4815 DLINK_FOREACH(node, global_client_list.head)
106 adx 30 {
107 michael 4815 ac2ptr = node->data;
108 adx 30
109 michael 4815 if (!match(name, ac2ptr->name))
110 adx 30 break;
111     else
112     ac2ptr = NULL;
113     }
114     }
115    
116 michael 3246 if (ac2ptr)
117 michael 3109 sendto_one_numeric(source_p, &me, RPL_TRACELINK,
118 michael 4815 ircd_version, name, ac2ptr->from->name);
119 adx 30 else
120 michael 3109 sendto_one_numeric(source_p, &me, RPL_TRACELINK,
121 michael 4815 ircd_version, name, "ac2ptr_is_NULL!!");
122 michael 2820 return 0;
123 adx 30 }
124 michael 1121
125 adx 30 case HUNTED_ISME:
126 michael 1149 do_actual_trace(source_p, parc, parv);
127 adx 30 break;
128     default:
129 michael 2820 return 0;
130 adx 30 }
131 michael 2820
132     return 0;
133 adx 30 }
134    
135 michael 1149 /*
136     ** ms_trace
137 michael 3096 ** parv[0] = command
138 michael 1149 ** parv[1] = servername
139     */
140 michael 2820 static int
141 michael 3156 ms_trace(struct Client *source_p, int parc, char *parv[])
142 michael 1149 {
143 michael 3156 if (hunt_server(source_p, ":%s TRACE %s :%s",
144 michael 2863 2, parc, parv) != HUNTED_ISME)
145 michael 2820 return 0;
146 michael 1149
147 michael 1219 if (HasUMode(source_p, UMODE_OPER))
148 michael 3156 return mo_trace(source_p, parc, parv);
149 michael 2820 return 0;
150 michael 1149 }
151    
152     static void
153 michael 889 do_actual_trace(struct Client *source_p, int parc, char *parv[])
154 adx 30 {
155     struct Client *target_p = NULL;
156     int doall = 0;
157 michael 889 int wilds, dow;
158 michael 4815 dlink_node *node;
159     const char *name;
160 adx 30
161     if (parc > 1)
162 michael 4815 name = parv[1];
163 adx 30 else
164 michael 4815 name = me.name;
165 adx 30
166 michael 1618 sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE,
167 michael 1144 "TRACE requested by %s (%s@%s) [%s]",
168     source_p->name, source_p->username,
169     source_p->host, source_p->servptr->name);
170    
171 michael 4815 if (!match(name, me.name))
172 michael 1243 doall = 1;
173 michael 4815 else if (!MyClient(source_p) && !strcmp(name, me.id))
174 adx 30 {
175 michael 1243 doall = 1;
176 michael 4815 name = me.name;
177 adx 30 }
178    
179 michael 4815 wilds = !parv[1] || has_wildcards(name);
180 adx 30 dow = wilds || doall;
181    
182 michael 1219 if (!HasUMode(source_p, UMODE_OPER) || !dow) /* non-oper traces must be full nicks */
183 adx 30 /* lets also do this for opers tracing nicks */
184     {
185 michael 4815 target_p = hash_find_client(name);
186 michael 2345
187 michael 2820 if (target_p && IsClient(target_p))
188 adx 30 {
189 michael 1219 if (HasUMode(target_p, UMODE_OPER))
190 adx 30 {
191 michael 3109 sendto_one_numeric(source_p, &me, RPL_TRACEOPERATOR,
192 michael 4815 get_client_class(&target_p->connection->confs), get_client_name(target_p, HIDE_IP),
193 michael 4967 target_p->sockhost,
194 michael 4588 CurrentTime - target_p->connection->lasttime,
195 michael 1783 idle_time_get(source_p, target_p));
196 adx 30 }
197     else
198     {
199 michael 3109 sendto_one_numeric(source_p, &me, RPL_TRACEUSER,
200 michael 4815 get_client_class(&target_p->connection->confs), get_client_name(target_p, HIDE_IP),
201 michael 4967 target_p->sockhost,
202 michael 4588 CurrentTime - target_p->connection->lasttime,
203 michael 1783 idle_time_get(source_p, target_p));
204 adx 30 }
205     }
206 michael 2345
207 michael 4815 sendto_one_numeric(source_p, &me, RPL_ENDOFTRACE, name);
208 adx 30 return;
209     }
210    
211     /* report all direct connections */
212 michael 4815 DLINK_FOREACH(node, local_client_list.head)
213 adx 30 {
214 michael 4815 target_p = node->data;
215 adx 30
216 michael 1219 if (HasUMode(target_p, UMODE_INVISIBLE) && dow &&
217 michael 2345 !(MyConnect(source_p) && HasUMode(source_p, UMODE_OPER)) &&
218     !HasUMode(target_p, UMODE_OPER) && (target_p != source_p))
219 adx 30 continue;
220 michael 4815 if (!doall && wilds && match(name, target_p->name))
221 adx 30 continue;
222 michael 4815 if (!dow && irccmp(name, target_p->name))
223 adx 30 continue;
224    
225 michael 889 report_this_status(source_p, target_p, dow);
226 adx 30 }
227    
228 michael 4815 DLINK_FOREACH(node, local_server_list.head)
229 adx 30 {
230 michael 4815 target_p = node->data;
231 adx 30
232 michael 4815 if (!doall && wilds && match(name, target_p->name))
233 adx 30 continue;
234 michael 4815 if (!dow && irccmp(name, target_p->name))
235 adx 30 continue;
236    
237 michael 889 report_this_status(source_p, target_p, dow);
238 adx 30 }
239    
240     /* This section is to report the unknowns */
241 michael 4815 DLINK_FOREACH(node, unknown_list.head)
242 adx 30 {
243 michael 4815 target_p = node->data;
244 adx 30
245 michael 4815 if (!doall && wilds && match(name, target_p->name))
246 adx 30 continue;
247 michael 4815 if (!dow && irccmp(name, target_p->name))
248 adx 30 continue;
249    
250 michael 889 report_this_status(source_p, target_p, dow);
251 adx 30 }
252    
253 michael 4815 DLINK_FOREACH(node, class_get_list()->head)
254 adx 30 {
255 michael 4815 const struct ClassItem *class = node->data;
256 michael 889
257 michael 1632 if (class->ref_count > 0)
258 michael 3109 sendto_one_numeric(source_p, &me, RPL_TRACECLASS, class->name, class->ref_count);
259 adx 30 }
260    
261 michael 4815 sendto_one_numeric(source_p, &me, RPL_ENDOFTRACE, name);
262 adx 30 }
263    
264     /* report_this_status()
265     *
266     * inputs - pointer to client to report to
267     * - pointer to client to report about
268     * output - counter of number of hits
269     * side effects - NONE
270     */
271 michael 889 static void
272     report_this_status(struct Client *source_p, struct Client *target_p, int dow)
273 adx 30 {
274     const char *name;
275     const char *class_name;
276    
277     name = get_client_name(target_p, HIDE_IP);
278 michael 4588 class_name = get_client_class(&target_p->connection->confs);
279 adx 30
280 michael 889 switch (target_p->status)
281 adx 30 {
282     case STAT_CONNECTING:
283 michael 3109 sendto_one_numeric(source_p, &me, RPL_TRACECONNECTING, class_name,
284 michael 4967 HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name);
285 adx 30 break;
286     case STAT_HANDSHAKE:
287 michael 3109 sendto_one_numeric(source_p, &me, RPL_TRACEHANDSHAKE, class_name,
288 michael 4967 HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name);
289 adx 30 break;
290     case STAT_ME:
291     break;
292     case STAT_UNKNOWN:
293 michael 3109 sendto_one_numeric(source_p, &me, RPL_TRACEUNKNOWN, class_name,
294 michael 4967 name, target_p->sockhost,
295     CurrentTime - target_p->connection->firsttime);
296 adx 30 break;
297     case STAT_CLIENT:
298 michael 4967 if (HasUMode(target_p, UMODE_OPER))
299     sendto_one_numeric(source_p, &me, RPL_TRACEOPERATOR, class_name, name,
300     target_p->sockhost,
301     CurrentTime - target_p->connection->lasttime,
302     idle_time_get(source_p, target_p));
303     else
304     sendto_one_numeric(source_p, &me, RPL_TRACEUSER, class_name, name,
305     target_p->sockhost,
306     CurrentTime - target_p->connection->lasttime,
307     idle_time_get(source_p, target_p));
308 adx 30 break;
309     case STAT_SERVER:
310 michael 889 {
311 michael 2262 unsigned int clients = 0;
312     unsigned int servers = 0;
313 michael 889
314     trace_get_dependent(&servers, &clients, target_p);
315    
316 michael 1219 if (!HasUMode(source_p, UMODE_ADMIN))
317 adx 30 name = get_client_name(target_p, MASK_IP);
318    
319 michael 3109 sendto_one_numeric(source_p, &me, RPL_TRACESERVER, class_name, servers,
320 michael 4967 clients, name, *(target_p->serv->by) ?
321     target_p->serv->by : "*", "*",
322     me.name, CurrentTime - target_p->connection->lasttime);
323 adx 30 break;
324 michael 889 }
325 michael 2820
326 michael 3109 default: /* ...we actually shouldn't come here... --msa */
327     sendto_one_numeric(source_p, &me, RPL_TRACENEWTYPE, name);
328 adx 30 break;
329     }
330     }
331 michael 1230
332 michael 2820 static struct Message trace_msgtab =
333     {
334 michael 4545 "TRACE", NULL, 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
335 michael 1230 { m_unregistered, m_trace, ms_trace, m_ignore, mo_trace, m_ignore }
336     };
337    
338     static void
339     module_init(void)
340     {
341     mod_add_cmd(&trace_msgtab);
342     }
343    
344     static void
345     module_exit(void)
346     {
347     mod_del_cmd(&trace_msgtab);
348     }
349    
350 michael 2820 struct module module_entry =
351     {
352 michael 1230 .node = { NULL, NULL, NULL },
353     .name = NULL,
354     .version = "$Revision$",
355     .handle = NULL,
356     .modinit = module_init,
357     .modexit = module_exit,
358     .flags = 0
359     };

Properties

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