Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
src/detstats.c | 6 ++---
src/itrafmon.c | 70 +++++++++++++++++++++++++-------------------------------
src/packet.c | 52 +++++++++++++++++++++++++++++++++++------
src/packet.h | 25 +++++++++++---------
src/serv.c | 13 +++++------
5 files changed, 98 insertions(+), 68 deletions(-)
diff --git a/src/detstats.c b/src/detstats.c
index 2364662..4eebdaf 100644
--- a/src/detstats.c
+++ b/src/detstats.c
@@ -259,7 +259,6 @@ void detstats(char *iface, const struct OPTIONS *options, time_t
facilitytime,
WINDOW *statwin;
PANEL *statpanel;
- struct iphdr *ipacket = NULL;
struct ip6_hdr *ip6packet = NULL;
int framelen = 0;
@@ -562,9 +561,8 @@ void detstats(char *iface, const struct OPTIONS *options, time_t
facilitytime,
continue;
}
- ipacket = (struct iphdr *) pkt.pkt_payload;
- iplen = ntohs(ipacket->tot_len);
- ipproto = ipacket->protocol;
+ iplen = ntohs(pkt.iphdr->tot_len);
+ ipproto = pkt.iphdr->protocol;
update_proto_counter(&ifcounts.ipv4, outgoing, iplen);
break;
diff --git a/src/itrafmon.c b/src/itrafmon.c
index ce68688..c2baaf7 100644
--- a/src/itrafmon.c
+++ b/src/itrafmon.c
@@ -552,8 +552,6 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
{
int logging = options->logging;
- struct iphdr *ippacket;
- struct ip6_hdr *ip6packet;
unsigned int protocol;
unsigned int frag_off;
struct tcphdr *transpacket; /* IP-encapsulated packet */
@@ -1019,17 +1017,13 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
switch(pkt.pkt_protocol) {
case ETH_P_IP:
- ippacket = (struct iphdr *) pkt.pkt_payload;
- iphlen = ippacket->ihl * 4;
- ip6packet = NULL;
- protocol = ippacket->protocol;
- frag_off = ippacket->frag_off;
+ iphlen = pkt.iphdr->ihl * 4;
+ protocol = pkt.iphdr->protocol;
+ frag_off = pkt.iphdr->frag_off;
break;
case ETH_P_IPV6:
- ip6packet = (struct ip6_hdr *) pkt.pkt_payload;
iphlen = 40;
- ippacket = NULL;
- protocol = ip6packet->ip6_nxt;
+ protocol = pkt.ip6_hdr->ip6_nxt;
frag_off = 0;
break;
default:
@@ -1045,11 +1039,11 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
transpacket = (struct tcphdr *) (pkt.pkt_payload + iphlen);
if (protocol == IPPROTO_TCP) {
- if (ippacket != NULL) {
+ if (pkt.iphdr) {
tcpentry =
in_table(&table,
- ippacket->saddr,
- ippacket->daddr,
+ pkt.iphdr->saddr,
+ pkt.iphdr->daddr,
NULL, NULL,
ntohs(sport),
ntohs(dport),
@@ -1058,14 +1052,12 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
} else {
tcpentry =
in_table(&table, 0, 0,
- (uint8_t *) (&ip6packet->
- ip6_src.
- s6_addr),
- (uint8_t *) (&ip6packet->
- ip6_dst.
- s6_addr),
- ntohs(sport), ntohs(dport),
- ifname, logging, logfile, options);
+ (uint8_t *) &pkt.ip6_hdr->
+ ip6_src.s6_addr,
+ (uint8_t *) &pkt.ip6_hdr->
+ ip6_dst.s6_addr,
+ ntohs(sport), ntohs(dport),
+ ifname, logging, logfile, options);
}
/*
@@ -1082,21 +1074,21 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
* is not yet closed, or if it is a SYN packet.
*/
wasempty = (table.head == NULL);
- if (ippacket != NULL)
+ if (pkt.iphdr)
tcpentry =
addentry(&table,
- (unsigned long) ippacket->saddr,
- (unsigned long) ippacket->daddr,
+ (unsigned long) pkt.iphdr->saddr,
+ (unsigned long) pkt.iphdr->daddr,
NULL, NULL, sport, dport,
- ippacket->protocol,
+ pkt.iphdr->protocol,
ifname, &revlook, rvnfd,
options->servnames);
else
tcpentry =
addentry(&table, 0, 0,
- (uint8_t *) (&ip6packet->ip6_src.s6_addr),
- (uint8_t *) (&ip6packet->ip6_dst.s6_addr),
- sport, dport, ip6packet->ip6_nxt,
+ (uint8_t *) &pkt.ip6_hdr->ip6_src.s6_addr,
+ (uint8_t *) &pkt.ip6_hdr->ip6_dst.s6_addr,
+ sport, dport, pkt.ip6_hdr->ip6_nxt,
ifname, &revlook, rvnfd,
options->servnames);
if (tcpentry != NULL) {
@@ -1128,10 +1120,10 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
p_dstat = tcpentry->d_fstat;
}
- if (ippacket != NULL)
+ if (pkt.iphdr)
updateentry(&table, tcpentry, transpacket,
pkt.pkt_buf, pkt.pkt_hatype,
- pkt.pkt_len, br, ippacket->frag_off,
+ pkt.pkt_len, br, pkt.iphdr->frag_off,
logging, &revlook, rvnfd, options,
logfile);
else
@@ -1190,10 +1182,10 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
printentry(&table, tcpentry->oth_connection,
screen_idx, mode);
}
- } else if (ippacket != NULL) {
- fragment = ((ntohs(ippacket->frag_off) & 0x1fff) != 0);
+ } else if (pkt.iphdr) {
+ fragment = ((ntohs(pkt.iphdr->frag_off) & 0x1fff) != 0);
- if (ippacket->protocol == IPPROTO_ICMP) {
+ if (pkt.iphdr->protocol == IPPROTO_ICMP) {
/*
* Cancel the corresponding TCP entry if an ICMP
@@ -1205,23 +1197,23 @@ void ipmon(struct OPTIONS *options, struct filterstate *ofilter,
process_dest_unreach(&table, (char *) transpacket,
ifname);
}
- add_othp_entry(&othptbl, &pkt, ippacket->saddr,
- ippacket->daddr, NULL, NULL, IS_IP,
- ippacket->protocol,
+ add_othp_entry(&othptbl, &pkt, pkt.iphdr->saddr,
+ pkt.iphdr->daddr, NULL, NULL, IS_IP,
+ pkt.iphdr->protocol,
(char *) transpacket,
ifname, &revlook, rvnfd,
logging, logfile,
options->servnames, fragment);
} else {
- if (ip6packet->ip6_nxt == IPPROTO_ICMPV6
+ if (pkt.ip6_hdr->ip6_nxt == IPPROTO_ICMPV6
&& (((struct icmp6_hdr *) transpacket)->icmp6_type ==
ICMP6_DST_UNREACH))
process_dest_unreach(&table, (char *) transpacket,
ifname);
add_othp_entry(&othptbl, &pkt, 0, 0,
- &ip6packet->ip6_src, &ip6packet->ip6_dst,
- IS_IP, ip6packet->ip6_nxt,
+ &pkt.ip6_hdr->ip6_src, &pkt.ip6_hdr->ip6_dst,
+ IS_IP, pkt.ip6_hdr->ip6_nxt,
(char *) transpacket, ifname,
&revlook, rvnfd,
logging, logfile, options->servnames,
diff --git a/src/packet.c b/src/packet.c
index fbd94f1..2da6686 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -20,6 +20,23 @@ packet.c - routines to open the raw socket, read socket data and
#include "packet.h"
#include "ipfrag.h"
+#define pkt_cast_hdrp_l2off_t(hdr, pkt, off) \
+ do { \
+ pkt->hdr = (struct hdr *) pkt->pkt_buf + off; \
+ } while (0)
+
+#define pkt_cast_hdrp_l2(hdr, pkt) \
+ pkt_cast_hdrp_l2off_t(hdr, pkt, 0)
+
+
+#define pkt_cast_hdrp_l3off_t(hdr, pkt, off) \
+ do { \
+ pkt->hdr = (struct hdr *) pkt->pkt_payload + off; \
+ } while (0)
+
+#define pkt_cast_hdrp_l3(hdr, pkt) \
+ pkt_cast_hdrp_l3off_t(hdr, pkt, 0)
+
/* code taken from
http://www.faqs.org/rfcs/rfc1071.html. See section 4.1 "C"
*/
static int in_cksum(u_short * addr, int len)
{
@@ -46,7 +63,7 @@ static int packet_adjust(struct pkt_hdr *pkt)
switch (pkt->pkt_hatype) {
case ARPHRD_ETHER:
case ARPHRD_LOOPBACK:
- pkt_cast_hdrp(ethhdr, pkt, 0);
+ pkt_cast_hdrp_l2(ethhdr, pkt);
pkt->pkt_payload = pkt->pkt_buf;
pkt->pkt_payload += ETH_HLEN;
pkt->pkt_len -= ETH_HLEN;
@@ -76,7 +93,7 @@ static int packet_adjust(struct pkt_hdr *pkt)
pkt->pkt_len -= 4;
break;
case ARPHRD_FDDI:
- pkt_cast_hdrp(fddihdr, pkt, 0);
+ pkt_cast_hdrp_l2(fddihdr, pkt);
pkt->pkt_payload = pkt->pkt_buf;
pkt->pkt_payload += sizeof(struct fddihdr);
pkt->pkt_len -= sizeof(struct fddihdr);
@@ -92,6 +109,26 @@ static int packet_adjust(struct pkt_hdr *pkt)
return retval;
}
+/* initialize all layer3 protocol pointers (we need to initialize all
+ * of them, because of case we change pkt->pkt_protocol) */
+static void packet_set_l3_hdrp(struct pkt_hdr *pkt)
+{
+ switch (pkt->pkt_protocol) {
+ case ETH_P_IP:
+ pkt_cast_hdrp_l3(iphdr, pkt);
+ pkt->ip6_hdr = NULL;
+ break;
+ case ETH_P_IPV6:
+ pkt->iphdr = NULL;
+ pkt_cast_hdrp_l3(ip6_hdr, pkt);
+ break;
+ default:
+ pkt->iphdr = NULL;
+ pkt->ip6_hdr = NULL;
+ break;
+ }
+}
+
/* IPTraf input function; reads both keystrokes and network packets. */
int packet_get(int fd, struct pkt_hdr *pkt, int *ch, WINDOW *win)
{
@@ -114,7 +151,7 @@ int packet_get(int fd, struct pkt_hdr *pkt, int *ch, WINDOW *win)
ss = poll(pfds, nfds, DEFAULT_UPDATE_DELAY / 1000);
} while ((ss == -1) && (errno == EINTR));
- pkt->pkt_len = 0; /* signalize we have no packet prepared */
+ PACKET_INIT_STRUCT(pkt);
if ((ss > 0) && (pfds[0].revents & POLLIN) != 0) {
struct sockaddr_ll from;
socklen_t fromlen = sizeof(struct sockaddr_ll);
@@ -155,8 +192,10 @@ int packet_process(struct pkt_hdr *pkt, unsigned int *total_br,
if (packet_adjust(pkt) != 0)
return INVALID_PACKET;
-again: if (pkt->pkt_protocol == ETH_P_IP) {
- struct iphdr *ip;
+again:
+ packet_set_l3_hdrp(pkt);
+ if (pkt->pkt_protocol == ETH_P_IP) {
+ struct iphdr *ip = pkt->iphdr;
int hdr_check;
register int ip_checksum;
register int iphlen;
@@ -166,7 +205,6 @@ again: if (pkt->pkt_protocol == ETH_P_IP) {
* At this point, we're now processing IP packets. Start by getting
* IP header and length.
*/
- ip = (struct iphdr *) (pkt->pkt_payload);
iphlen = ip->ihl * 4;
/*
@@ -260,7 +298,7 @@ again: if (pkt->pkt_protocol == ETH_P_IP) {
} else if (pkt->pkt_protocol == ETH_P_IPV6) {
struct tcphdr *tcp;
struct udphdr *udp;
- struct ip6_hdr *ip6 = (struct ip6_hdr *) pkt->pkt_payload;
+ struct ip6_hdr *ip6 = pkt->ip6_hdr;
char *ip_payload = (char *) ip6 + 40;
//TODO: Filter packets
diff --git a/src/packet.h b/src/packet.h
index 72a7062..f032a39 100644
--- a/src/packet.h
+++ b/src/packet.h
@@ -35,22 +35,25 @@ struct pkt_hdr {
unsigned char pkt_addr[8]; /* Physical layer address */
struct ethhdr *ethhdr;
struct fddihdr *fddihdr;
+ struct iphdr *iphdr;
+ struct ip6_hdr *ip6_hdr;
char pkt_buf[MAX_PACKET_SIZE];
};
-#define pkt_cast_hdrp(hdr, pkt, off) \
- do { \
- pkt->hdr = (struct hdr *) pkt->pkt_buf + off; \
- } while (0)
-
+static inline void PACKET_INIT_STRUCT(struct pkt_hdr *p)
+{
+ p->pkt_bufsize = MAX_PACKET_SIZE;
+ p->pkt_payload = NULL;
+ p->ethhdr = NULL;
+ p->fddihdr = NULL;
+ p->iphdr = NULL;
+ p->ip6_hdr = NULL;
+ p->pkt_len = 0; /* signalize we have no packet prepared */
+}
#define PACKET_INIT(packet) \
- struct pkt_hdr packet = { \
- .pkt_bufsize = MAX_PACKET_SIZE, \
- .pkt_payload = NULL, \
- .ethhdr = NULL, \
- .fddihdr = NULL, \
- };
+ struct pkt_hdr packet; \
+ PACKET_INIT_STRUCT(&packet)
void open_socket(int *fd);
int packet_get(int fd, struct pkt_hdr *pkt, int *ch, WINDOW *win);
diff --git a/src/serv.c b/src/serv.c
index aeea6b2..caa8a6c 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -1048,9 +1048,6 @@ void servmon(char *ifname, const struct OPTIONS *options,
if (pkt.pkt_len <= 0)
continue;
- unsigned short ipproto;
- unsigned short iplen;
-
pkt_result =
packet_process(&pkt, &tot_br, &sport, &dport,
ofilter,
@@ -1060,14 +1057,16 @@ void servmon(char *ifname, const struct OPTIONS *options,
if (pkt_result != PACKET_OK)
continue;
+ unsigned short ipproto;
+ unsigned short iplen;
switch (pkt.pkt_protocol) {
case ETH_P_IP:
- ipproto = ((struct iphdr *) pkt.pkt_payload)->protocol;
- iplen = ntohs(((struct iphdr *) pkt.pkt_payload)->tot_len);
+ ipproto = pkt.iphdr->protocol;
+ iplen = ntohs(pkt.iphdr->tot_len);
break;
case ETH_P_IPV6:
- ipproto = ((struct ip6_hdr *) pkt.pkt_payload)->ip6_nxt; /* FIXME: extension
headers ??? */
- iplen = ntohs(((struct ip6_hdr *) pkt.pkt_payload)->ip6_plen) + 40;
+ ipproto = pkt.ip6_hdr->ip6_nxt; /* FIXME: extension headers ??? */
+ iplen = ntohs(pkt.ip6_hdr->ip6_plen) + 40;
break;
default:
/* unknown link protocol */
--
1.7.10.2