Refactor node so that it does not modify mbuf contents. Next step would
be pass-thru mode, when traffic is not copied by ng_tee, but passed thru ng_netflow. Changes made: - In ng_netflow_rcvdata() do all necessary pulluping: Ethernet header, IP header, and TCP/UDP header. - Pass only pointer to struct ip to ng_netflow_flow_add(). Any TCP/UDP headers are guaranteed to by after it. - Merge make_flow_rec() function into ng_netflow_flow_add().
This commit is contained in:
parent
1d03bd1684
commit
2b38b68736
@ -426,49 +426,98 @@ ng_netflow_rcvdata (hook_p hook, item_p item)
|
|||||||
ERROUT(EINVAL);
|
ERROUT(EINVAL);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* increase counters */
|
/* Increase counters. */
|
||||||
iface->info.ifinfo_packets++;
|
iface->info.ifinfo_packets++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Depending on interface data link type and packet contents
|
||||||
|
* we pullup enough data, so that ng_netflow_flow_add() does not
|
||||||
|
* need to know about mbuf at all. We keep current length of data
|
||||||
|
* needed to be contiguous in pullup_len. mtod() is done at the
|
||||||
|
* very end one more time, since m can had changed after pulluping.
|
||||||
|
*
|
||||||
|
* In case of unrecognized data we don't return error, but just
|
||||||
|
* pass data to downstream hook, if it is available.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define M_CHECK(length) do { \
|
||||||
|
pullup_len += length; \
|
||||||
|
if ((m)->m_pkthdr.len < (pullup_len)) { \
|
||||||
|
error = EINVAL; \
|
||||||
|
goto done; \
|
||||||
|
} \
|
||||||
|
if ((m)->m_len < (pullup_len) && \
|
||||||
|
(((m) = m_pullup((m),(pullup_len))) == NULL)) { \
|
||||||
|
error = ENOBUFS; \
|
||||||
|
goto done; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
switch (iface->info.ifinfo_dlt) {
|
switch (iface->info.ifinfo_dlt) {
|
||||||
case DLT_EN10MB: /* Ethernet */
|
case DLT_EN10MB: /* Ethernet */
|
||||||
{
|
{
|
||||||
struct ether_header *eh;
|
struct ether_header *eh;
|
||||||
uint16_t etype;
|
uint16_t etype;
|
||||||
|
|
||||||
if (CHECK_MLEN(m, (sizeof(struct ether_header))))
|
M_CHECK(sizeof(struct ether_header));
|
||||||
ERROUT(EINVAL);
|
|
||||||
|
|
||||||
if (CHECK_PULLUP(m, (sizeof(struct ether_header))))
|
|
||||||
ERROUT(ENOBUFS);
|
|
||||||
|
|
||||||
eh = mtod(m, struct ether_header *);
|
eh = mtod(m, struct ether_header *);
|
||||||
|
|
||||||
/* make sure this is IP frame */
|
/* Make sure this is IP frame. */
|
||||||
etype = ntohs(eh->ether_type);
|
etype = ntohs(eh->ether_type);
|
||||||
switch (etype) {
|
switch (etype) {
|
||||||
case ETHERTYPE_IP:
|
case ETHERTYPE_IP:
|
||||||
m_adj(m, sizeof(struct ether_header));
|
M_CHECK(sizeof(struct ip));
|
||||||
|
eh = mtod(m, struct ether_header *);
|
||||||
|
ip = (struct ip *)(eh + 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROUT(EINVAL); /* ignore this frame */
|
goto done; /* pass this frame */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DLT_RAW: /* IP packets */
|
||||||
|
M_CHECK(sizeof(struct ip));
|
||||||
|
ip = mtod(m, struct ip *);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto done;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In case of IP header with options, we haven't pulled
|
||||||
|
* up enough, yet.
|
||||||
|
*/
|
||||||
|
pullup_len += (ip->ip_hl << 2) - sizeof(struct ip);
|
||||||
|
|
||||||
|
switch (ip->ip_p) {
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
M_CHECK(sizeof(struct tcphdr));
|
||||||
|
break;
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
M_CHECK(sizeof(struct udphdr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (iface->info.ifinfo_dlt) {
|
||||||
|
case DLT_EN10MB:
|
||||||
|
{
|
||||||
|
struct ether_header *eh;
|
||||||
|
|
||||||
|
eh = mtod(m, struct ether_header *);
|
||||||
|
ip = (struct ip *)(eh + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DLT_RAW:
|
case DLT_RAW:
|
||||||
|
ip = mtod(m, struct ip *);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROUT(EINVAL);
|
panic("ng_netflow entered deadcode");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_MLEN(m, sizeof(struct ip)))
|
#undef M_CHECK
|
||||||
ERROUT(EINVAL);
|
|
||||||
|
|
||||||
if (CHECK_PULLUP(m, sizeof(struct ip)))
|
error = ng_netflow_flow_add(priv, ip, iface, m->m_pkthdr.rcvif);
|
||||||
ERROUT(ENOBUFS);
|
|
||||||
|
|
||||||
error = ng_netflow_flow_add(priv, &m, iface);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (item)
|
if (item)
|
||||||
|
Loading…
Reference in New Issue
Block a user