Skip to content

Commit ebdcfdf

Browse files
authored
Merge pull request #18 from git-hulk/fix/determine-packet-type
MOD: determine the packet type
2 parents 4008248 + 9641a9c commit ebdcfdf

File tree

7 files changed

+102
-23
lines changed

7 files changed

+102
-23
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ A tool to capture tcp packets and analyze the packets with LUA.
66

77
```
88
TCPKIT is a tool to capture tcp packets and analyze the packets with lua.
9-
-s which server ip to monitor, e.g. 192.168.1.2,192.168.1.3
9+
-s which server ip to monitor, must specify when runing in client side. e.g. 192.168.1.2,192.168.1.3
1010
-p which n_latency to monitor, e.g. 6379,6380
1111
-P stats listen port, default is 33333
1212
-i network card interface, e.g. bond0, lo, em0... see 'ifconfig'
@@ -36,7 +36,7 @@ $ sudo make && make install
3636
Supports Redis/Memcached/DNS protocol now, we take Redis as example here:
3737

3838
```
39-
$ sudo tcpkit -i em1 -p 6379,6380,6381 -t 10 -m redis
39+
$ sudo tcpkit -i em1 -s 192.168.1.2 -p 6379,6380,6381 -t 10 -m redis
4040
```
4141

4242
and the request latency more than 10ms would be printed, like below:
@@ -48,6 +48,7 @@ and the request latency more than 10ms would be printed, like below:
4848

4949
Tcpkit would print all requests if the `-t` option wasn't set.
5050
If tcpkit was deployed client-side, use the `-s` option to specify the server host/ip.
51+
> Caution: `-s` option should be specified when tcpkit is running in client side or decode packets from offline pcap.
5152
5253
## Use lua to analyze packets
5354

src/hashtable.c

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,18 @@ void hashtable_destroy(hashtable *ht) {
9292
}
9393

9494
int hashtable_add(hashtable *ht, char *key, void *value) {
95-
int bucket;
95+
int bucket, key_size, current_key_size;
9696
entry *current;
9797

98+
key_size = strlen(key);
9899
bucket = hash_function(key, strlen(key)) % ht->nbucket;
99100
current = ht->buckets[bucket];
100101
while (current) {
101-
if (!strncasecmp(key, current->key, strlen(current->key))) return 0;
102+
current_key_size = strlen(current->key);
103+
if (key_size == current_key_size
104+
&& !strncmp(key, current->key, key_size)){
105+
return 0;
106+
}
102107
current = current->next;
103108
}
104109
entry *e = malloc(sizeof(*e));
@@ -110,39 +115,45 @@ int hashtable_add(hashtable *ht, char *key, void *value) {
110115
}
111116

112117
void *hashtable_get(hashtable *ht, char *key) {
113-
int bucket;
118+
int bucket, key_size, current_key_size;
114119
entry *current;
115120

116-
bucket = hash_function(key, strlen(key)) % ht->nbucket;
121+
key_size = strlen(key);
122+
bucket = hash_function(key, key_size) % ht->nbucket;
117123
current = ht->buckets[bucket];
118124
while(current) {
119-
if (!strncasecmp(key, current->key, strlen(current->key))) {
120-
return current->value;
125+
current_key_size = strlen(current->key);
126+
if (current_key_size == key_size
127+
&& !strncmp(key, current->key, key_size)) {
128+
return current->value;
121129
}
122130
current = current->next;
123131
}
124132
return NULL;
125133
}
126134

127135
int hashtable_del(hashtable *ht, char *key) {
128-
int bucket;
129-
entry *next, *prev;
136+
int bucket, key_size=strlen(key), current_key_size;
137+
entry *current, *prev;
130138

131-
bucket = hash_function(key, strlen(key)) % ht->nbucket;
132-
prev = next = ht->buckets[bucket];
133-
while (next) {
134-
if (!strncasecmp(key, next->key, strlen(next->key))) {
135-
prev->next = next->next;
136-
free(next->key);
137-
ht->free ? ht->free(next->value):free(next->value);
138-
free(next);
139-
if (prev == ht->buckets[bucket]) {
139+
bucket = hash_function(key, key_size) % ht->nbucket;
140+
prev = current = ht->buckets[bucket];
141+
142+
while (current) {
143+
current_key_size = strlen(current->key);
144+
if (key_size == current_key_size
145+
&& !strncmp(key, current->key, key_size)) {
146+
prev->next = current->next;
147+
if (current == ht->buckets[bucket]) {
140148
ht->buckets[bucket] = NULL;
141149
}
150+
free(current->key);
151+
ht->free ? ht->free(current->value):free(current->value);
152+
free(current);
142153
return 1;
143154
}
144-
prev = next;
145-
next = next->next;
155+
prev = current;
156+
current = current->next;
146157
}
147158
return 0;
148159
}

src/packet.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,15 @@ static void process_udp_packet(server *srv, user_packet *packet) {
232232
}
233233

234234
static int8_t is_request(server *srv, user_packet *packet) {
235+
int i;
236+
235237
if (packet->sport != packet->dport) {
236238
return port_in_target(srv, packet->dport) != -1;
237239
}
238-
// TODO; corner case src port == dst port
239-
return 1;
240+
for (i = 0; i < srv->n_server; i++) {
241+
if (srv->servers[i].s_addr == packet->dip.s_addr) return 1;
242+
}
243+
return 0;
240244
}
241245

242246
void extract_packet_handler(unsigned char *user,

src/server.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <lua.h>
2727
#include <pcap/pcap.h>
2828
#include <netinet/in.h>
29+
#include <arpa/inet.h>
2930

3031
#include "server.h"
3132
#include "tcpikt.h"
@@ -36,12 +37,40 @@
3637
#include "logger.h"
3738

3839
int server_init(server *srv) {
40+
int i, n_server;
41+
char *server_str;
42+
struct array *local_addresses;
43+
3944
srv->stop = 0;
4045
srv->req_ht = hashtable_create(102400);
4146
if (!srv->req_ht) return -1;
4247
srv->st = stats_create(array_used(srv->opts->ports));
4348
if (!srv->st) return -1;
4449
server_create_stats_thread(srv);
50+
51+
srv->n_server = 0;
52+
srv->servers = NULL;
53+
n_server = array_used(srv->opts->servers);
54+
if (n_server > 0) {
55+
srv->n_server = n_server;
56+
srv->servers = malloc(n_server * sizeof(struct in_addr));
57+
for (i = 0; i < n_server; i++) {
58+
server_str = *(char **)array_pos(srv->opts->servers, i);
59+
inet_pton(AF_INET, server_str, &srv->servers[i]);
60+
}
61+
} else {
62+
// fetch server ip from nic
63+
local_addresses = get_addresses_from_device();
64+
if (local_addresses) {
65+
srv->n_server = array_used(local_addresses);
66+
srv->servers = malloc(srv->n_server * sizeof(struct in_addr));
67+
for (i = 0; i < srv->n_server; i++) {
68+
memcpy(&srv->servers[i], (struct in_addr*)array_pos(local_addresses, i),
69+
sizeof(struct in_addr));
70+
}
71+
array_dealloc(local_addresses);
72+
}
73+
}
4574
return 0;
4675
}
4776

@@ -55,6 +84,7 @@ void server_deinit(server *srv) {
5584
if (srv->filter) free(srv->filter);
5685
if (srv->st) stats_destroy(srv->st);
5786
if (srv->req_ht) hashtable_destroy(srv->req_ht);
87+
if (srv->servers) free(srv->servers);
5888

5989
options *opts = srv->opts;
6090
if (opts) {

src/tcpikt.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ typedef struct {
5252
hashtable *req_ht;
5353
pthread_t stats_tid;
5454
int stop;
55+
struct in_addr *servers;
56+
int n_server;
5557
} server;
5658

5759
typedef enum {

src/util.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
#include <stdio.h>
1717
#include <stdlib.h>
1818
#include <string.h>
19+
#include <sys/types.h>
20+
#include <sys/socket.h>
21+
#include <ifaddrs.h>
22+
#include <netinet/in.h>
23+
#include <arpa/inet.h>
1924

2025
#include "util.h"
2126
#include "array.h"
@@ -63,3 +68,26 @@ void free_split_string(struct array *arr) {
6368
}
6469
array_dealloc(arr);
6570
}
71+
72+
struct array *get_addresses_from_device() {
73+
struct ifaddrs *if_addrs, *ifa;
74+
struct in_addr in_addr;
75+
struct array *addrs;
76+
char *elem;
77+
78+
if (getifaddrs(&if_addrs) == -1) {
79+
return NULL;
80+
}
81+
addrs = array_alloc(sizeof(struct in_addr), 5);
82+
for (ifa = if_addrs; ifa; ifa = ifa->ifa_next) {
83+
if (!ifa->ifa_addr) continue;
84+
if (ifa->ifa_addr->sa_family == AF_INET || ifa->ifa_addr->sa_family == AF_INET6) {
85+
in_addr = ((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
86+
if (!in_addr.s_addr) continue;
87+
elem = array_push(addrs);
88+
memcpy(elem, &in_addr, sizeof(struct in_addr));
89+
}
90+
}
91+
freeifaddrs(if_addrs);
92+
return addrs;
93+
}

src/util.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#ifndef TCPKIT_UTIL_H
1818
#define TCPKIT_UTIL_H
1919

20+
#include "array.h"
21+
2022
struct array *split_string(char *input, char delim);
2123
void free_split_string(struct array *arr);
24+
struct array *get_addresses_from_device();
2225
#endif //TCPKIT_UTIL_H

0 commit comments

Comments
 (0)