-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathmonitor.c
More file actions
123 lines (95 loc) · 3.63 KB
/
Copy pathmonitor.c
File metadata and controls
123 lines (95 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* monitor.c — Proceso de supervisión de SecureBank
* - Lee los mensajes que envían usuarios por la cola SYSV (clave 1234)
* - Muestra la transacción por pantalla y la añade a transacciones.log
* - Detecta patrones sencillos de fraude (retiros y transferencias repetitivas) */
#define _POSIX_C_SOURCE 200809L /* strptime, etc. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include "utils.h"
/* ────────── Constantes ────────── */
#define MSG_KEY 1234
#define TAM_MAX 128
/* ────────── Configuración (sólo umbrales) ────────── */
typedef struct {
int umbral_retiros;
int umbral_transferencias;
char archivo_log[64];
} Cfg;
static Cfg cfg;
/* ────────── Mensaje recibido ───────── */
struct msgbuf {
long tipo;
char texto[TAM_MAX];
};
/* ────────── Estado para la detección de anomalías ────────── */
static int retiros_consecutivos[10000] = {0};
static int transferencias_rep[10000][10000] = {{0}};
/* ────────── Utilidades ────────── */
static void timestamp(char *dst, size_t n)
{
time_t t = time(NULL);
struct tm tm = *localtime(&t);
strftime(dst, n, "[%Y-%m-%d %H:%M:%S]", &tm);
}
/* ────────── Reglas de anomalía ────────── */
static void analizar(const char *msg)
{
int origen, destino;
float monto;
if (sscanf(msg, "RETIRO %d %f", &origen, &monto) == 2) {
if (++retiros_consecutivos[origen] >= cfg.umbral_retiros) {
char alerta[128];
snprintf(alerta, sizeof alerta,
"ALERTA: %d retiros seguidos en cuenta %d",
cfg.umbral_retiros, origen);
puts(alerta);
append_log(cfg.archivo_log, alerta);
retiros_consecutivos[origen] = 0;
}
} else if (sscanf(msg, "TRANSFERENCIA %d %d %f",
&origen, &destino, &monto) == 3) {
if (++transferencias_rep[origen][destino] >= cfg.umbral_transferencias) {
char alerta[160];
snprintf(alerta, sizeof alerta,
"ALERTA: %d transferencias seguidas de %d a %d",
cfg.umbral_transferencias, origen, destino);
puts(alerta);
append_log(cfg.archivo_log, alerta);
transferencias_rep[origen][destino] = 0;
}
} else if (sscanf(msg, "DEPOSITO %d %f", &origen, &monto) == 2) {
/* reinicia contador de retiros cuando llega un depósito */
retiros_consecutivos[origen] = 0;
}
}
/* ────────── main ────────── */
int main(void)
{
Config cfg;
cfg = leer_config("config.txt");
int qid = msgget(MSG_KEY, IPC_CREAT | 0666);
if (qid == -1) { perror("msgget"); exit(EXIT_FAILURE); }
puts("Monitor activo. Esperando transacciones…");
struct msgbuf m;
for (;;)
{
if (msgrcv(qid, &m, sizeof m.texto, 0, 0) == -1)
{
if (errno == EINTR) continue;
perror("msgrcv");
break;
}
char ts[32];
timestamp(ts, sizeof ts);
printf("%s %s\n", ts, m.texto);
append_log(cfg.archivo_log, m.texto);
analizar(m.texto); /* reglas de fraude */
}
return 0;
}