00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026 #include "handlers.h"
00027 #include "tools.h"
00028 #include "hook.h"
00029 #include "client.h"
00030 #include "hash.h"
00031 #include "common.h"
00032 #include "irc_string.h"
00033 #include "ircd.h"
00034 #include "numeric.h"
00035 #include "fdlist.h"
00036 #include "s_bsd.h"
00037 #include "s_conf.h"
00038 #include "s_serv.h"
00039 #include "send.h"
00040 #include "msg.h"
00041 #include "parse.h"
00042 #include "modules.h"
00043 #include "irc_getnameinfo.h"
00044
00045 static void do_ctrace(struct Client *, int, char **);
00046 static void mo_ctrace(struct Client *, struct Client *, int, char *[]);
00047
00048 struct Message ctrace_msgtab = {
00049 "CTRACE", 0, 0, 2, 0, MFLG_SLOW, 0,
00050 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_ctrace, m_ignore}
00051 };
00052
00053 #ifndef STATIC_MODULES
00054 const char *_version = "$Revision: 309 $";
00055 static struct Callback *ctrace_cb;
00056
00057 static void *
00058 va_ctrace(va_list args)
00059 {
00060 struct Client *source_p = va_arg(args, struct Client *);
00061 int parc = va_arg(args, int);
00062 char **parv = va_arg(args, char **);
00063
00064 do_ctrace(source_p, parc, parv);
00065 return NULL;
00066 }
00067
00068 void
00069 _modinit(void)
00070 {
00071 ctrace_cb = register_callback("doing_ctrace", va_ctrace);
00072 mod_add_cmd(&ctrace_msgtab);
00073 }
00074
00075 void
00076 _moddeinit(void)
00077 {
00078 mod_del_cmd(&ctrace_msgtab);
00079 uninstall_hook(ctrace_cb, va_ctrace);
00080 }
00081 #endif
00082
00083 static int report_this_status(struct Client *, struct Client *);
00084
00085
00086
00087
00088
00089
00090 static void
00091 mo_ctrace(struct Client *client_p, struct Client *source_p,
00092 int parc, char *parv[])
00093 {
00094 if (EmptyString(parv[1]))
00095 {
00096 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
00097 me.name, parv[0], "CTRACE");
00098 return;
00099 }
00100
00101 #ifdef STATIC_MODULES
00102 do_ctrace(source_p, parc, parv);
00103 #else
00104 execute_callback(ctrace_cb, source_p, parc, parv);
00105 #endif
00106 }
00107
00108
00109
00110
00111 static void
00112 do_ctrace(struct Client *source_p, int parc, char **parv)
00113 {
00114 struct Client *target_p = NULL;
00115 char *class_looking_for;
00116 const char *class_name;
00117 dlink_node *ptr;
00118
00119 class_looking_for = parv[1];
00120
00121
00122
00123 DLINK_FOREACH(ptr, local_client_list.head)
00124 {
00125 target_p = ptr->data;
00126
00127 class_name = get_client_class(target_p);
00128 if ((class_name != NULL) && match(class_looking_for, class_name))
00129 report_this_status(source_p, target_p);
00130 }
00131
00132 sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name,
00133 parv[0], class_looking_for);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 static int
00145 report_this_status(struct Client *source_p, struct Client *target_p)
00146 {
00147 const char *name = NULL;
00148 const char *class_name = NULL;
00149 char ip[HOSTIPLEN];
00150 int cnt = 0;
00151
00152
00153 irc_getnameinfo((struct sockaddr*)&target_p->localClient->ip,
00154 target_p->localClient->ip.ss_len, ip, HOSTIPLEN, NULL, 0,
00155 NI_NUMERICHOST);
00156 name = get_client_name(target_p, HIDE_IP);
00157 class_name = get_client_class(target_p);
00158
00159 switch(target_p->status)
00160 {
00161 case STAT_CLIENT:
00162
00163 if ((IsOper(source_p) &&
00164 (MyClient(source_p) || !IsInvisible(target_p)))
00165 || IsOper(target_p))
00166 {
00167 if (IsAdmin(target_p) && !ConfigFileEntry.hide_spoof_ips)
00168 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
00169 me.name, source_p->name, class_name, name,
00170 IsAdmin(source_p) ? ip : "255.255.255.255",
00171 CurrentTime - target_p->lasttime,
00172 CurrentTime - target_p->localClient->last);
00173 else if (IsOper(target_p))
00174 {
00175 if (ConfigFileEntry.hide_spoof_ips)
00176 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
00177 me.name, source_p->name, class_name, name,
00178 IsIPSpoof(target_p) ? "255.255.255.255" : ip,
00179 CurrentTime - target_p->lasttime,
00180 CurrentTime - target_p->localClient->last);
00181 else
00182 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
00183 me.name, source_p->name, class_name, name,
00184 (IsIPSpoof(target_p) ? "255.255.255.255" : ip),
00185 CurrentTime - target_p->lasttime,
00186 CurrentTime - target_p->localClient->last);
00187 }
00188 else
00189 {
00190 if (ConfigFileEntry.hide_spoof_ips)
00191 sendto_one(source_p, form_str(RPL_TRACEUSER),
00192 me.name, source_p->name, class_name, name,
00193 IsIPSpoof(target_p) ? "255.255.255.255" : ip,
00194 CurrentTime - target_p->lasttime,
00195 CurrentTime - target_p->localClient->last);
00196 else
00197 sendto_one(source_p, form_str(RPL_TRACEUSER),
00198 me.name, source_p->name, class_name, name,
00199 (IsIPSpoof(target_p) ? "255.255.255.255" : ip),
00200 CurrentTime - target_p->lasttime,
00201 CurrentTime - target_p->localClient->last);
00202 }
00203 cnt++;
00204 }
00205 break;
00206 case STAT_SERVER:
00207 if(!IsAdmin(source_p))
00208 name = get_client_name(target_p, MASK_IP);
00209
00210 sendto_one(source_p, form_str(RPL_TRACESERVER),
00211 me.name, source_p->name, class_name, 0,
00212 0, name, *(target_p->serv->by) ?
00213 target_p->serv->by : "*", "*",
00214 me.name, CurrentTime - target_p->lasttime);
00215 cnt++;
00216 break;
00217
00218 default:
00219 sendto_one(source_p, form_str(RPL_TRACENEWTYPE), me.name,
00220 source_p->name, name);
00221 cnt++;
00222 break;
00223 }
00224
00225 return cnt;
00226 }