Skip to content

Commit 05be4a4

Browse files
authored
Add files via upload
1 parent 9474fe9 commit 05be4a4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+72908
-0
lines changed

hw1/Makefile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CXX = g++
2+
exe = 0516205_hw1
3+
obj = main.o utils.o
4+
5+
.PHONY: all clean
6+
7+
all: $(obj)
8+
$(CXX) $(obj) -o $(exe)
9+
10+
%.o: %.cpp
11+
$(CXX) -c $?
12+
13+
clean:
14+
rm $(exe) $(obj)

hw1/main.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
#include <getopt.h>
5+
#include <sys/types.h>
6+
#include <dirent.h>
7+
#include <string.h>
8+
#include <arpa/inet.h>
9+
#include <errno.h>
10+
#include <string>
11+
#include <unordered_map>
12+
#include <regex>
13+
#include <iostream>
14+
15+
#include "utils.h"
16+
17+
int main(int argc, char **argv)
18+
{
19+
int flag_tcp = 0;
20+
int flag_udp = 0;
21+
const char *path_tcp = "/proc/net/tcp";
22+
const char *path_tcp_6 = "/proc/net/tcp6";
23+
const char *path_udp = "/proc/net/udp";
24+
const char *path_udp_6 = "/proc/net/udp6";
25+
std::unordered_map<std::string, std::string> Hash_inode_table;
26+
std::vector <std::regex> filter;
27+
28+
parse_cmdline(argc, argv, &flag_tcp, &flag_udp, filter);
29+
create_inode_table(Hash_inode_table);
30+
31+
// for( const auto& n : Hash_inode_table )
32+
// std::cout << "Key:[" << n.first << "] Value:[" << n.second << "]\n";
33+
34+
if (flag_tcp) {
35+
printf("List of TCP connections:\n");
36+
printf("%-8s%-20s%-20s%-30s\n", "Proto", "Local Address", "Foreign Address", "PID/Program name and arguments");
37+
show_tcp_status(path_tcp, Hash_inode_table, filter);
38+
show_tcp_status(path_tcp_6, Hash_inode_table, filter);
39+
}
40+
if (flag_tcp && flag_udp)
41+
printf("\n");
42+
if (flag_udp) {
43+
printf("List of UDP connections:\n");
44+
printf("%-8s%-20s%-20s%-30s\n", "Proto", "Local Address", "Foreign Address", "PID/Program name and arguments");
45+
show_udp_status(path_udp, Hash_inode_table, filter);
46+
show_udp_status(path_udp_6, Hash_inode_table, filter);
47+
}
48+
49+
return 0;
50+
}
51+

hw1/utils.cpp

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
#include <getopt.h>
5+
#include <sys/types.h>
6+
#include <dirent.h>
7+
#include<string.h>
8+
#include <arpa/inet.h>
9+
#include <string>
10+
#include <unordered_map>
11+
#include <regex>
12+
13+
#include "utils.h"
14+
15+
void create_inode_table (std::unordered_map<std::string, std::string> &Hash_inode_table) {
16+
DIR *DIR_layer1, *DIR_layer2;
17+
struct dirent *dirent_layer1, *dirent_layer2;
18+
const char *path_proc = "/proc";
19+
20+
DIR_layer1 = opendir(path_proc);
21+
if (DIR_layer1 == NULL) {
22+
fprintf(stderr,"Ls: can not open %s", path_proc);
23+
} else {
24+
while ((dirent_layer1 = readdir(DIR_layer1)) != NULL) {
25+
if (is_valid_directory(dirent_layer1)) {
26+
char *file_path = (char*)malloc(100);
27+
sprintf(file_path, "%s/%s/fd", path_proc, dirent_layer1->d_name);
28+
DIR_layer2 = opendir(file_path);
29+
while ((dirent_layer2 = readdir(DIR_layer2)) != NULL) {
30+
if (dirent_layer2->d_type == DT_LNK) {
31+
char* link_path = (char*)malloc(100);
32+
char* symlink = (char*)malloc(100);
33+
sprintf(link_path, "%s/%s", file_path, dirent_layer2->d_name);
34+
int result = readlink(link_path, symlink, 100);
35+
if (result == -1)
36+
printf("cannot read link %s\n", link_path);
37+
else {
38+
symlink[result] = '\0';
39+
// printf("symlink: %s\n", symlink);
40+
// printf("process: %s\n", dirent_layer1->d_name);
41+
// printf("inode: %s\n", inode);
42+
std::string inode = find_inode_by_symlink(symlink);
43+
Hash_inode_table[inode] = dirent_layer1->d_name;
44+
}
45+
}
46+
}
47+
}
48+
}
49+
}
50+
closedir(DIR_layer1);
51+
closedir(DIR_layer2);
52+
}
53+
54+
void show_tcp_status (const char* path, std::unordered_map<std::string, std::string> &Hash_inode_table, std::vector <std::regex> &filter) {
55+
FILE *fp;
56+
char *buf;
57+
size_t ret;
58+
const char *delim = "\t\r\n ";
59+
int ROW_COUNT = 17;
60+
fp = fopen(path, "rb");
61+
buf = (char*)malloc(BUFFER_SIZE);
62+
ret = fread(buf, 1, BUFFER_SIZE, fp);
63+
// printf("%s\n", buf); // print "/proc/net/tcp" data
64+
fclose(fp);
65+
66+
char* local_ip = (char*)malloc(10);
67+
char* local_port = (char*)malloc(10);
68+
char* rem_ip = (char*)malloc(10);
69+
char* rem_port = (char*)malloc(10);
70+
std::string inode;
71+
std::string pid;
72+
char* proc_name = (char*)malloc(50);
73+
int mode;
74+
75+
if (strcmp(path, "/proc/net/tcp") == 0)
76+
mode = AF_INET;
77+
else
78+
mode = AF_INET6;
79+
80+
char *token = strtok(buf, delim);
81+
for (int i = 1; token != NULL; i++) {
82+
if (i > 12) {
83+
int index = normalize_tcp_index(i);
84+
// local_address
85+
if (index % ROW_COUNT == 2) {
86+
local_ip = parse_address(token, mode);
87+
local_port = parse_port(token, mode);
88+
}
89+
// rem_address
90+
if (index % ROW_COUNT == 3) {
91+
rem_ip = parse_address(token, mode);
92+
rem_port = parse_port(token, mode);
93+
}
94+
// inode
95+
if (index % ROW_COUNT == 10) {
96+
inode = token;
97+
auto result = Hash_inode_table.find(inode);
98+
if (result != Hash_inode_table.end()) {
99+
pid = result->second.c_str();
100+
proc_name = find_proc_name(pid);
101+
if (is_filter_cmd(filter, std::string(proc_name))) {
102+
char* local_addr = (char*)malloc(20);
103+
char* rem_addr = (char*)malloc(20);
104+
char* pid_pname = (char*)malloc(50);
105+
sprintf(local_addr, "%s:%s", local_ip, local_port);
106+
sprintf(rem_addr, "%s:%s", rem_ip, rem_port);
107+
sprintf(pid_pname, "%s/%s", pid.c_str(), proc_name);
108+
if (mode == AF_INET)
109+
printf("%-8s%-20s%-20s%-30s\n", "tcp", local_addr, rem_addr, pid_pname);
110+
else
111+
printf("%-8s%-20s%-20s%-30s\n", "tcp6", local_addr, rem_addr, pid_pname);
112+
}
113+
} else {
114+
printf("Not found tcp\n");
115+
}
116+
}
117+
}
118+
token = strtok(NULL, delim);
119+
}
120+
}
121+
122+
void show_udp_status (const char* path, std::unordered_map<std::string, std::string> &Hash_inode_table, std::vector <std::regex> &filter) {
123+
FILE *fp;
124+
char *buf;
125+
size_t ret;
126+
const char *delim = " \t\r\n ";
127+
int ROW_COUNT = 13;
128+
fp = fopen(path, "rb");
129+
buf = (char*)malloc(BUFFER_SIZE);
130+
ret = fread(buf, 1, BUFFER_SIZE, fp);
131+
// printf("%s\n", buf); // print "/proc/net/udp" data
132+
fclose(fp);
133+
134+
char* local_ip = (char*)malloc(10);
135+
char* local_port = (char*)malloc(10);
136+
char* rem_ip = (char*)malloc(10);
137+
char* rem_port = (char*)malloc(10);
138+
std::string inode;
139+
std::string pid;
140+
char* proc_name = (char*)malloc(50);
141+
int mode;
142+
143+
if (strcmp(path, "/proc/net/udp") == 0)
144+
mode = AF_INET;
145+
else
146+
mode = AF_INET6;
147+
148+
char *token = strtok(buf, delim);
149+
for (int i = 1; token != NULL; i++) {
150+
if (i > 15) {
151+
int index = normalize_udp_index(i);
152+
// local_address
153+
if (index % ROW_COUNT == 2) {
154+
local_ip = parse_address(token, mode);
155+
local_port = parse_port(token, mode);
156+
}
157+
// rem_address
158+
if (index % ROW_COUNT == 3) {
159+
rem_ip = parse_address(token, mode);
160+
rem_port = parse_port(token, mode);
161+
}
162+
// inode
163+
if (index % ROW_COUNT == 10) {
164+
inode = std::string(token);
165+
auto result = Hash_inode_table.find(inode);
166+
if (result != Hash_inode_table.end()) {
167+
pid = result->second.c_str();
168+
proc_name = find_proc_name(pid);
169+
if (is_filter_cmd(filter, std::string(proc_name))) {
170+
char* local_addr = (char*)malloc(20);
171+
char* rem_addr = (char*)malloc(20);
172+
char* pid_pname = (char*)malloc(50);
173+
sprintf(local_addr, "%s:%s", local_ip, local_port);
174+
sprintf(rem_addr, "%s:%s", rem_ip, rem_port);
175+
sprintf(pid_pname, "%s/%s", pid.c_str(), proc_name);
176+
if (mode == AF_INET)
177+
printf("%-8s%-20s%-20s%-30s\n", "udp", local_addr, rem_addr, pid_pname);
178+
else
179+
printf("%-8s%-20s%-20s%-30s\n", "udp6", local_addr, rem_addr, pid_pname);
180+
}
181+
} else {
182+
printf("Not found udp\n");
183+
}
184+
}
185+
}
186+
token = strtok(NULL, delim);
187+
}
188+
}
189+
190+
bool is_filter_cmd(std::vector <std::regex> &filter, std::string proc_name) {
191+
if (filter.size() == 0)
192+
return true;
193+
for (auto &reg_filter_cmd: filter)
194+
if (std::regex_match(proc_name.begin(), proc_name.end(), reg_filter_cmd))
195+
return true;
196+
return false;
197+
}
198+
199+
char* find_proc_name (std::string pid) {
200+
FILE *fp;
201+
char *file_path = (char*)malloc(100);
202+
char *proc_name;
203+
size_t ret;
204+
sprintf(file_path, "/proc/%s/comm", pid.c_str());
205+
fp = fopen(file_path, "rb");
206+
proc_name = (char*)malloc(100);
207+
ret = fread(proc_name, 1, 100, fp);
208+
209+
// remove new line character
210+
int length = 0;
211+
while(proc_name[length] != '\0') {
212+
if (proc_name[length] == '\n') {
213+
proc_name[length] = '\0';
214+
break;
215+
}
216+
length++;
217+
}
218+
return proc_name;
219+
}
220+
221+
std::string find_inode_by_symlink (char* symlink) {
222+
std::string inode;
223+
std::string s = std::string(symlink);
224+
unsigned int inode_tmp;
225+
std::regex reg("socket:\[[0-9]*]"); // ex: socket:[123]
226+
227+
if (std::regex_match(s.begin(), s.end(), reg))
228+
sscanf(s.substr(8, s.length()-9).c_str(), "%u", &inode_tmp);
229+
inode = std::to_string(inode_tmp);
230+
return inode;
231+
}
232+
233+
char* parse_port (char* token, int mode) {
234+
char* port = (char*)malloc(10);
235+
unsigned port_x;
236+
unsigned addr[4];
237+
if (mode == AF_INET)
238+
sscanf(token, "%x:%x", &addr[0], &port_x);
239+
else
240+
sscanf(token, "%8x%8x%8x%8x:%x", &addr[0], &addr[1], &addr[2], &addr[3], &port_x);
241+
if(port_x == 0)
242+
sprintf(port, "*");
243+
else
244+
sprintf(port, "%d", port_x);
245+
246+
return port;
247+
}
248+
249+
char* parse_address (char* token, int mode) {
250+
unsigned addr[4];
251+
char* addr_tmp = (char*)malloc(50);
252+
int mode_max_len;
253+
254+
if (mode == AF_INET) {
255+
mode_max_len = INET_ADDRSTRLEN;
256+
sscanf(token, "%x:", &addr[0]);
257+
} else {
258+
mode_max_len = INET6_ADDRSTRLEN;
259+
sscanf(token, "%8x%8x%8x%8x:", &addr[0], &addr[1], &addr[2], &addr[3]);
260+
}
261+
inet_ntop(mode, &addr[0], addr_tmp, mode_max_len);
262+
263+
return addr_tmp;
264+
}
265+
266+
bool is_valid_directory (struct dirent *ptr) {
267+
if (ptr->d_type == DT_DIR
268+
&& strcmp(ptr->d_name, ".") != 0
269+
&& strcmp(ptr->d_name, "..") != 0
270+
&& ptr->d_name[0] > 47
271+
&& ptr->d_name[0] < 58) {
272+
return true;
273+
}
274+
return false;
275+
}
276+
277+
int normalize_udp_index (int index) {
278+
return index - 15 - (((index - 15) / 13) * 13);
279+
}
280+
281+
int normalize_tcp_index (int index) {
282+
return index - 12 - (((index - 12) / 17) * 17);
283+
}
284+
285+
void parse_cmdline(int argc, char *argv[], int *flag_tcp, int *flag_udp, std::vector <std::regex> &filter) {
286+
int result;
287+
int longindex = 0; // null
288+
const char *optstring = "tu";
289+
290+
static struct option long_options[] = {
291+
{"tcp", no_argument, NULL, 't'},
292+
{"udp", no_argument, NULL, 'u'},
293+
};
294+
295+
// parse filter cmd
296+
for(int i = 1; i < argc; i++) {
297+
if(argv[i][0]!='-') {
298+
std::string reg_filter_cmd;
299+
reg_filter_cmd = ".*";
300+
reg_filter_cmd = reg_filter_cmd + argv[i] + ".*";
301+
filter.push_back(std::regex(reg_filter_cmd.c_str()));
302+
}
303+
}
304+
305+
while ((result = getopt_long(argc, argv, optstring, long_options, &longindex)) != -1) {
306+
switch (result) {
307+
case 't':
308+
*flag_tcp = 1;
309+
break;
310+
case 'u':
311+
*flag_udp = 1;
312+
break;
313+
default:
314+
break;
315+
}
316+
}
317+
}
318+

0 commit comments

Comments
 (0)