ICMP6通过socket_raw抓取ND_NEIGHBOR_SOLICIT

haxzheng 2010-06-25 10:48:26
通过socket_raw监听icmp6的报文,只能抓去到RA与RS的报文,无法获取NS的报文。请高手指教

#include <stdio.h>
#include <netinet/ip.h>
#include <netinet/in_systm.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#include <errno.h>


#define BUFSIZE 2048
#define HASHNAMESIZE 4096
struct h6namemem {
struct in6_addr addr;
char *name;
struct h6namemem *nxt;
};
struct h6namemem h6nametable[HASHNAMESIZE];

void process(char *ptr,ssize_t len,struct msghdr *msg,struct timeval *tvrecv);
const char * getname6(const u_char *ap);
struct h6namemem * newh6namemem(void);

struct sockaddr *sarecv;
int salen;
pid_t pid;

static int ci = 0;
int main(int argc,char ** argv)
{
printf("Starting...\n");

int size;
char recvbuf[BUFSIZE];
char controlbuf[BUFSIZE];
struct msghdr msg;
struct iovec iov;
ssize_t n;
struct timeval tval;

int sockfd;

sockfd=socket(PF_INET6,SOCK_RAW,IPPROTO_ICMPV6);
setuid(getuid());
pid = getpid()&0xffff;
int on=1;
struct icmp6_filter myfilter;
//ICMP6_FILTER_SETBLOCKALL(&myfilter);
//ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY,&myfilter);
ICMP6_FILTER_SETPASSALL(&myfilter);
setsockopt(sockfd,IPPROTO_IPV6,ICMP6_FILTER,&myfilter,sizeof(myfilter));

on = 255;
setsockopt(sockfd,SOL_SOCKET,IPV6_MULTICAST_HOPS,&on,sizeof(on));

iov.iov_base = recvbuf;
iov.iov_len = sizeof(recvbuf);
msg.msg_name = sarecv;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = controlbuf;

while(1)
{
msg.msg_namelen = salen;
msg.msg_controllen = sizeof(controlbuf);
n = recvmsg(sockfd,&msg,0);
if(n<0)
continue;
process(msg.msg_iov->iov_base,n,&msg,&tval);
}

printf("done\n");
exit(0);
}

void process(char *ptr,ssize_t len,struct msghdr *msg,struct timeval *tvrecv)
{
printf("processing...\tcnt:%d\n",ci++);

struct icmp6_hdr *icmp6;
struct timeval *tvsend;
struct cmsghdr *cmsg;
int hlim;

icmp6 = (struct icmp6_hdr *)ptr;


//ND_NEIGHBOR_SOLICIT
if(icmp6->icmp6_type == ND_NEIGHBOR_SOLICIT)
{
if(icmp6->icmp6_id!= pid){
// printf("pid error\n");
// return;
}

struct nd_neighbor_solicit *p;
p = (struct nd_neighbor_solicit *)ptr;

printf(", who has %s", getname6(&p->nd_ns_target));

//printf("IPV6ADDR:\t%s",Sock_ntop_host(sarecv,salen));

}
printf("ICMP6_TYPE:\t%d\tICMP_CODE:\t%d\n",icmp6->icmp6_type,icmp6->icmp6_code);
printf("------------------------\n");
}

const char *
getname6(const u_char *ap)
{
register struct hostent *hp;
struct in6_addr addr;
static struct h6namemem *p; /* static for longjmp() */
register const char *cp;
char ntop_buf[INET6_ADDRSTRLEN];

memcpy(&addr, ap, sizeof(addr));
p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)];
for (; p->nxt; p = p->nxt) {
if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
return (p->name);
}
p->addr = addr;
p->nxt = newh6namemem();


cp = inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf));
p->name = strdup(cp);
return (p->name);
}
struct h6namemem *
newh6namemem(void)
{
register struct h6namemem *p;
static struct h6namemem *ptr = NULL;
static u_int num = 0;

if (num <= 0) {
num = 64;
ptr = (struct h6namemem *)calloc(num, sizeof (*ptr));
if (ptr == NULL)
error("newh6namemem: calloc");
}
--num;
p = ptr++;
return (p);
}

...全文
225 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
haxzheng 2010-06-25
  • 打赏
  • 举报
回复
如果这种方法抓取不到NS的报文,请问用什么方法来处理?
另:除非没有办法,否则不从链路层来搞

4,356

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧