-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlog_to_file.c
148 lines (126 loc) · 3.23 KB
/
log_to_file.c
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* (c) 2008-2011 Daniel Halperin <[email protected]>
*/
#include "iwl_connector.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#define MAX_PAYLOAD 2048
#define SLOW_MSG_CNT 1
int sock_fd = -1; // the socket
FILE* out = NULL;
void check_usage(int argc, char** argv);
FILE* open_file(char* filename, char* spec);
void caught_signal(int sig);
void exit_program(int code);
void exit_program_err(int code, char* func);
int main(int argc, char** argv)
{
/* Local variables */
struct sockaddr_nl proc_addr, kern_addr; // addrs for recv, send, bind
struct cn_msg *cmsg;
char buf[4096];
int ret;
unsigned short l, l2;
int count = 0;
/* Make sure usage is correct */
check_usage(argc, argv);
/* Open and check log file */
out = open_file(argv[1], "w");
/* Setup the socket */
sock_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
if (sock_fd == -1)
exit_program_err(-1, "socket");
/* Initialize the address structs */
memset(&proc_addr, 0, sizeof(struct sockaddr_nl));
proc_addr.nl_family = AF_NETLINK;
proc_addr.nl_pid = getpid(); // this process' PID
proc_addr.nl_groups = CN_IDX_IWLAGN;
memset(&kern_addr, 0, sizeof(struct sockaddr_nl));
kern_addr.nl_family = AF_NETLINK;
kern_addr.nl_pid = 0; // kernel
kern_addr.nl_groups = CN_IDX_IWLAGN;
/* Now bind the socket */
if (bind(sock_fd, (struct sockaddr *)&proc_addr, sizeof(struct sockaddr_nl)) == -1)
exit_program_err(-1, "bind");
/* And subscribe to netlink group */
{
int on = proc_addr.nl_groups;
ret = setsockopt(sock_fd, 270, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
if (ret)
exit_program_err(-1, "setsockopt");
}
/* Set up the "caught_signal" function as this program's sig handler */
signal(SIGINT, caught_signal);
/* Poll socket forever waiting for a message */
while (1)
{
/* Receive from socket with infinite timeout */
ret = recv(sock_fd, buf, sizeof(buf), 0);
if (ret == -1)
exit_program_err(-1, "recv");
/* Pull out the message portion and print some stats */
cmsg = NLMSG_DATA(buf);
if (count % SLOW_MSG_CNT == 0)
printf("received %d bytes: id: %d val: %d seq: %d clen: %d\n", cmsg->len, cmsg->id.idx, cmsg->id.val, cmsg->seq, cmsg->len);
/* Log the data to file */
l = (unsigned short) cmsg->len;
l2 = htons(l);
fwrite(&l2, 1, sizeof(unsigned short), out);
ret = fwrite(cmsg->data, 1, l, out);
if (count % 100 == 0)
printf("wrote %d bytes [msgcnt=%u]\n", ret, count);
++count;
if (ret != l)
exit_program_err(1, "fwrite");
}
exit_program(0);
return 0;
}
void check_usage(int argc, char** argv)
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s <output_file>\n", argv[0]);
exit_program(1);
}
}
FILE* open_file(char* filename, char* spec)
{
FILE* fp = fopen(filename, spec);
if (!fp)
{
perror("fopen");
exit_program(1);
}
return fp;
}
void caught_signal(int sig)
{
fprintf(stderr, "Caught signal %d\n", sig);
exit_program(0);
}
void exit_program(int code)
{
if (out)
{
fclose(out);
out = NULL;
}
if (sock_fd != -1)
{
close(sock_fd);
sock_fd = -1;
}
exit(code);
}
void exit_program_err(int code, char* func)
{
perror(func);
exit_program(code);
}