atish bhowmick(deleted)
03/24/2014 7:49 AM
post109577
|
I have a packet filter implemented using the pfil interface which I am mounting into the io-pkt . In both the input and
output hooks , how do I extract information such as source & destination ip-address , port no of the packets ?
the hooks have signature : hook(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
how can I get all the relevant packet data coming in / going out inside these hooks functions which are getting called ?
Any information / sample code would be useful .
|
|
|
Nick Reilly
03/24/2014 9:50 AM
post109587
|
The packet is a struct mbuf * located in *m. It is going to depend on the parameters you passed to pfil_add_hook() on
whether you just have the IP layer or a full layer 2 packet (e.g. Ethernet layer). Also you need to watch out for
whether you have the full packet in one mbuf or whether it is distributed along a chain of mbufs requiring you to walk
the chain whilst traversing the packet.
Once you've got these things sorted out, you can just mtod() it and extract the fields directly.
|
|
|
atish bhowmick(deleted)
03/25/2014 8:44 AM
post109603
|
Hey Nick ,
thnx for ur reply ... i tried few things on mbuf today but without any success .
I have registered my output_hook as :
pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
pfil_add_hook(output_hook, NULL, PFIL_OUT | PFIL_WAITOK,pfh_inet);
So I am expecting IP layer data in my mbuf . The only data structure containing struct sock_addr inside struct mbuf is
pkthdr_data.rcvif of struct ifnet type . So i was trying to access this member to get port & ip information but its empty .
Also in my traversal i follow the next packet link but if i follow the next buffer link of same chain I get segmentation issues . Below is a code snippet of the hook function . Any pointers as to what I am doing wrong wud be very useful .
static int output_hook(void *arg, struct mbuf **m,
struct ifnet *ifp, int dir)
{
out_bytes += (*m)->m_len;
struct mbuf* trav = (*m);
do{
short mbuf_type = trav->m_type;
int mbuf_length = trav->m_len;
int mbuf_flags = trav->m_flags;
struct pkthdr pkthdr_data = trav->m_pkthdr;
struct ifnet *if_data = NULL;
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),
_SLOG_ERROR,
"in our output_hook() mbuf len:%d type:%d flags:%d",
mbuf_length,mbuf_type,mbuf_flags);
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),
_SLOG_ERROR,
"in our output_hook() packet hdr len:%d csumflags:%d csumdata:%u segsize:%u",
pkthdr_data.len,pkthdr_data.csum_flags,pkthdr_data.csum_data,pkthdr_data.segsz);
if_data = pkthdr_data.rcvif;
if(if_data)
{
struct sockaddr *dest_sa = NULL;
int fam = -1;
int port = -1;
if(if_data->if_dl && if_data->if_dl->ifa_dstaddr)
{
dest_sa = if_data->if_dl->ifa_dstaddr;
if(dest_sa){
port = ntohs(((struct sockaddr_in*)dest_sa)->sin_port);
fam = ((struct sockaddr_in*)dest_sa)->sin_family;
}
}
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),
_SLOG_ERROR,
"in our output_hook() socket info:%d %d",port,fam);
}
// go to next packet
trav=trav->m_nextpkt;
}while(NULL != trav);
return 0; // 0 means allow, 1 means block
}
TIA
Atish
|
|
|
atish bhowmick(deleted)
03/26/2014 9:42 AM
post109612
|
I had some success in walking thru the mbufs constituting the packet with some code modifications . The 1st mbuf is the
header foloowed by the data mbufs . I am able to traverse thru the mbufs and extract some info related to length of data
& packet . But I cant figure out the location of the ip layer information inside the data mbufs . when I access some of the char sequence members of the mbuf such as MH_databuf & M_databuf using mtod I get some sequence of chars . Am I looking in the wrong place ?
Pls give me some pointers .
Below is the code of the hook for reference :
static int output_hook(void *arg, struct mbuf **m,
struct ifnet *ifp, int dir)
{
out_bytes += (*m)->m_len;
struct mbuf* trav = (*m);
do{
short mbuf_type = trav->m_type;
int mbuf_length = trav->m_len;
int mbuf_flags = trav->m_flags;
//char * mbuf_hdrdata = (*m)->m_data;
//struct mowner * mbuf_owner = (*m)->m_owner;
//char * mbuf_data = (*m)->m_dat;
//char *mdata = (char *)malloc(mbuf_length+1);
//strncpy(mdata,mbuf_hdrdata,mbuf_length);
//mdata[mbuf_length]='\0';
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),
_SLOG_ERROR,
"in our output_hook() mbuf len:%d type:%d flags:%d",
mbuf_length,mbuf_type,mbuf_flags);
// found a packet header mbuf
if(M_PKTHDR == mbuf_flags)
{
struct pkthdr pkthdr_data = trav->m_pkthdr;
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),
_SLOG_ERROR,
"in our output_hook() packet hdr len:%d csumflags:%d csumdata:%u segsize:%u",
pkthdr_data.len,pkthdr_data.csum_flags,pkthdr_data.csum_data,pkthdr_data.segsz);
struct ifnet *if_data = NULL;
if_data = pkthdr_data.rcvif;
if(if_data)
{
struct sockaddr *dest_sa = NULL;
int fam = -1;
int port = -1;
if(if_data->if_dl && if_data->if_dl->ifa_dstaddr)
{
dest_sa = if_data->if_dl->ifa_dstaddr;
if(dest_sa){
port = ntohs(((struct sockaddr_in*)dest_sa)->sin_port);
fam = ((struct sockaddr_in*)dest_sa)->sin_family;
}
}
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),
_SLOG_ERROR,
"in our output_hook() socket info:%d %d",port,fam);
}
}
// found a data packet mbuf but where is it ???
else if(MT_DATA == mbuf_type )
{
//char databuffer[MLEN]= {0};
//strcpy(databuffer,trav->m_dat);
//char * databuffer = trav->m_dat;
//char *pdata = (char *)malloc(mbuf_length+1);
//strncpy(pdata,databuffer,mbuf_length);
//pdata[mbuf_length]='\0';
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() i m databuffer");
}
// go to next buf in chain
trav=trav->m_next;
}while(NULL != trav);
return 0; // 0 means allow, 1 means block
}
|
|
|
Nick Reilly
03/26/2014 2:13 PM
post109618
|
The mbuf contains the data on the wire, nothing to do with sockaddr. You need to do something like:
#include <netinet/ip.h>
struct ip *ip;
ip = mtod(*m, struct ip *);
Then you have the addresses in ip->ip_src, ip->ip_dst. The protocol in ip->ip_p will tell you what to cast the next
bunch of bytes to in order to decode them.
|
|
|
Nick Reilly
03/26/2014 2:15 PM
post109619
|
Forgot to mention, watch out that on output you may have a chain, always check (*m)->m_len before doing the mtod() to
make sure you have enough data there.
|
|
|
atish bhowmick(deleted)
03/27/2014 7:48 AM
post109629
|
Hey Nick ,
ur info helped a lot ... now I am able to read the IP header from mbuf & extract source & dest ip
address from the structure . I also need to read the TCp header & read port numbers . I tried offesetting to TCp header
from the IP header if the IP protocol value is 6 (TCP) & read port nos . but I am not sure I am getting proper values .
I want to filter out any http requests by detecting the destination port no = 80 , but right now I am mever getting the
value 80 after I invoke a http request using the browser . Below is the code snippet I have used ... any pointers as to
what might be wrong wud b immensely helpful .
struct ip *ipheader = NULL;
ipheader = mtod(trav,struct ip *);
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() mtod done for ip");
// lookout for TCP packets
if(ipheader && (6 == ipheader->ip_p))
{
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() source ip : %d:%d:%d:%d",
(int)(ipheader->ip_src.s_addr&0xFF),
(int)((ipheader->ip_src.s_addr&0xFF00)>>8),
(int)((ipheader->ip_src.s_addr&0xFF0000)>>16),
(int)((ipheader->ip_src.s_addr&0xFF000000)>>24));
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() dest ip : %d:%d:%d:%d",
(int)(ipheader->ip_dst.s_addr&0xFF),
(int)((ipheader->ip_dst.s_addr&0xFF00)>>8),
(int)((ipheader->ip_dst.s_addr&0xFF0000)>>16),
(int)((ipheader->ip_dst.s_addr&0xFF000000)>>24));
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() version : %d hdrl : %d length : %d",
ipheader->ip_v,ipheader->ip_hl,ipheader->ip_len);
struct tcphdr *tcpheader = NULL;
tcpheader= (struct tcphdr *)(ipheader + (ipheader->ip_hl*4));
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() mtod done for tcp");
if(tcpheader)
{
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() source port : %04x dest port : %04x",
tcpheader->th_sport,
tcpheader->th_dport);
}
}
TIA
Atish
|
|
|
atish bhowmick(deleted)
03/28/2014 7:26 AM
post109664
|
Hey Nick ,
with the help of ur info now I am able to read the port nos. inside the tcp header . I am getting the
port nos for qconn & phrelay Qnx services which are running but I am not getting the port no 80 corresponding to http request when I invoke the browser . Can u pls help if anything else needs to be done for http packets . Below is the code snippet which reads ip header & tcp header from mbuf in the outgoing hook :
if(mbuf_length > 0 )
{
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() i m databuffer");
struct ip *ipheader = NULL;
ipheader = mtod(trav,struct ip *);
// lookout for TCP packets
if(ipheader && (6 == ipheader->ip_p))
{
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() source ip : %d:%d:%d:%d",
(int)(ipheader->ip_src.s_addr&0xFF),
(int)((ipheader->ip_src.s_addr&0xFF00)>>8),
(int)((ipheader->ip_src.s_addr&0xFF0000)>>16),
(int)((ipheader->ip_src.s_addr&0xFF000000)>>24));
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() dest ip : %d:%d:%d:%d",
(int)(ipheader->ip_dst.s_addr&0xFF),
(int)((ipheader->ip_dst.s_addr&0xFF00)>>8),
(int)((ipheader->ip_dst.s_addr&0xFF0000)>>16),
(int)((ipheader->ip_dst.s_addr&0xFF000000)>>24));
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() version : %d hdrl : %d length : %d",
ipheader->ip_v,ipheader->ip_hl,ipheader->ip_len);
// offset to the tcp header which follows the ip header
struct tcphdr *tcpheader = NULL;
//tcpheader = mtod(trav,struct tcphdr *);
int iphdrsize = sizeof(struct ip);
tcpheader= (struct tcphdr *)((void *)ipheader + iphdrsize);
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() ip header size : %d",iphdrsize);
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() ip header location : %p",(void *)ipheader);
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() tcp header location : %p",(void *)tcpheader);
if(tcpheader)
{
slogf( _SLOG_SETCODE(_SLOGC_TEST, 2),_SLOG_ERROR,
"in our output_hook() source port : %04x dest port : %04x",
tcpheader->th_sport,tcpheader->th_dport);
}
}
}
TIA
Atish
|
|
|
atish bhowmick(deleted)
03/31/2014 2:49 AM
post109691
|
Hi Nick ,
I am able to extract data from IP & TCP headers .I am able to intercept all the phrelay/qconn packets being
exchanged . But I am not able to intercept any http packet when I invoke the browser and open any webpage . Please
provide any pointers as to whats required to intercept a http request packet .
Regards
Atish
|
|
|
|