网卡抓包:从同一个网卡收包后再发回这个网卡抓不到这个包吗?

zpzkitt 2013-12-06 01:33:24
假设我的eth0网卡的ip是192.168.1.10,其他机器(另一台实体机器)用tcp方式发送数据包到eth0上,然后我从eth0收的这些数据包,解析修改之后用udp的方式再将新的内容发送给eth0,同时我希望用tcpdump从eth0上能把我修改之后的数据包抓取下来。
问题:我抓不到我自己发送的数据包。为什么呢?
附上我自己写的发包和收包的代码
收包程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <assert.h>
#include <netdb.h>

#include <signal.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>

#define ASSIGN_BUF(dst, src, dst_size) \
*(dst++) = src; dst_size--;

#define RECV_BUFSIZE 65536 /* size of an I/O buffer */
#define SEND_BUFSIZE 2048

typedef struct { /* type of structure for a socket */
int recv_fd; /* recv socket */
char buf[RECV_BUFSIZE]; /* reading buffer */
char *rp; /* reading pointer */
char *ep; /* end pointer */
int end; /* end flag */
int soerrno;
int freetime;
} recv_socket;

typedef struct { /* type of structure for a socket */
int send_fd; /* send socket */
char buf[SEND_BUFSIZE]; /* reading buffer */
int buf_len;
} send_socket;

recv_socket *r_fd;
send_socket *s_fd;
char *recv_ip_port[3] = {0};
char *send_ip_port[3] = {0};
int task_runing;

void init_daemon(void)
{
int pid;
int i;
pid=fork();
if(pid > 0){
printf("exit1\n");
exit(0); //是父进程,结束父进程
}else if(pid< 0){
printf("exit2\n");
exit(1); //fork失败,退出
}else{
//是第一子进程,后台继续执行
setsid(); //第一子进程成为新的会话组长和进程组长
//并与控制终端分离
pid=fork();
if(pid > 0){
printf("exit3\n");
exit(0); //是第一子进程,结束第一子进程
}else if(pid < 0){
printf("exit4\n");
exit(1); //fork失败,退出
}else{
//是第二子进程,继续
//第二子进程不再是会话组长
for(i=0;i< NOFILE;++i){
close(i); //关闭打开的文件描述符
}

chdir("/tmp"); //改变工作目录到/tmp
umask(0); //重设文件创建掩模
}
}
return;
}


int recv_getc(recv_socket *recv_sock)
{
assert(recv_sock);

if(recv_sock->rp < recv_sock->ep){
// printf("%02x ", *(unsigned char *)(recv_sock->rp));
return *(unsigned char *)(recv_sock->rp++);
}

do {
int rv = recv(recv_sock->recv_fd, recv_sock->buf, RECV_BUFSIZE, 0);

#if 0
int i;
for(i = 0;i < 1024;i++){
printf("%02x ", (unsigned char)recv_sock->buf[i]);
}
printf("\n");
#endif

if(rv > 0){
recv_sock->rp = recv_sock->buf + 1;
recv_sock->ep = recv_sock->buf + rv;
return *(unsigned char *)recv_sock->buf;
} else if(rv == 0){
recv_sock->end = 1;
return -1;
}
} while(errno == EINTR);
if(errno == EAGAIN) {
recv_sock->soerrno = EAGAIN;
}
recv_sock->end = 1;
return -1;
}

int seg_len()
{

return -1;
}

int head_check(recv_socket *recv_sock)
{
assert(recv_sock);
uint16_t len;
int i, ret = 0;

/*jump two byte*/
recv_getc(recv_sock);
recv_getc(recv_sock);

/*get total len*/
len = (uint16_t)recv_getc(recv_sock) << 8;
len |= (uint16_t)recv_getc(recv_sock);

if(len < 20 || len > 1024){
printf("len error!\n");
return -1;
}

/*jump 12 byte*/
for(i = 0;i < 12;i++){
ret = recv_getc(recv_sock);
if(ret < 0){
printf("recv data failed!\n");
return -1;
}else if(ret != 0){
printf("check failed!\n");
return -2;
}
}
return len;
}

int get_data(recv_socket *recv_sock, char *buf, int size, int head_len)
{
uint16_t radius_len = 0, tmp = 0;
uint16_t c = 0;
/*jump 2 byte*/
c = recv_getc(recv_sock);
ASSIGN_BUF(buf, c, size)
c = recv_getc(recv_sock);
ASSIGN_BUF(buf, c, size)
/*get radius length*/
c = (uint16_t)recv_getc(recv_sock);
radius_len = c << 8;
ASSIGN_BUF(buf, c, size)
c = (uint16_t)recv_getc(recv_sock);
radius_len |= c;
ASSIGN_BUF(buf, c, size)

if(radius_len < 20 || radius_len > 1024 || (head_len != (radius_len + 12))){
printf("radius length error!\n");
return -2;
}
tmp += 4;
while(size > 0){
if((c = recv_getc(recv_sock)) < 0){
return -1;
}
*(buf++) = c;
size--;
if(++tmp == radius_len){
break;
}
}
return tmp;
}

int recv_pock(recv_socket *recv_sock, char *buf, int size)
{
assert(recv_sock && buf && size >= 0);
int ret = 0;

if((ret = head_check(recv_sock)) < 0){
printf("head check failed!\n");
return -1;
}
if((ret = get_data(recv_sock, buf, size, ret)) < 0){
return -1;
}
return ret; /*return radius len*/
}

int send_pock(send_socket *send_sock, char *buf, int buf_len)
{
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
if(inet_aton(send_ip_port[1], &addr.sin_addr) == 0){
printf("ipadd error!");
return -1;
}
int snum = atoi(send_ip_port[2]);
addr.sin_port = htons(snum);
int ret = 0;

#if 0
int i;
for(i = 0;i < 418;i++){
printf("%02x ", (unsigned char)buf[i]);
}
printf("\n");
#endif

ret = sendto(send_sock->send_fd, buf, buf_len, 0, (struct sockaddr*)&addr, sizeof(addr));
if(ret != buf_len){
printf("send error!\n");
return -1;
}
return 0;
}

int init_recv_sock(char *argv[])
{
int ret;

if((r_fd->recv_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0){
perror("recv socket:");
return -1;
}

struct sockaddr_in client_addr;
bzero(&client_addr,sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = htons(INADDR_ANY);
client_addr.sin_port = htons(0);

if((ret = bind(r_fd->recv_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))) != 0){
perror("recv bind:");
return -1;
}

struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;

if(inet_aton(argv[1], &server_addr.sin_addr) == 0) {
printf("ipaddr error!\n");
return -1;
}
int snum = atoi(argv[2]);

server_addr.sin_port = htons(snum);
if(connect(r_fd->recv_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) != 0){
perror("recv connect");
return -1;
}
return 0;
}

int deinit_recv_sock()
{
close(r_fd->recv_fd);
return 0;
}

int init_send_sock(char *argv[])
{
if((s_fd->send_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0){
perror("send socket");
return -1;
}

#if 0
if(bind(s_fd->send_fd, (struct sockaddr*)&addr, sizeof(addr)) != 0){
perror("send bind");
return -1;
}
#endif
return 0;
}

int deinit_send_sock()
{
close(s_fd->send_fd);
return 0;
}

int init_socket(int argc, char *argv[])
{
if(argc != 0){
recv_ip_port[1] = argv[1];
recv_ip_port[2] = argv[2];

send_ip_port[1] = argv[3];
send_ip_port[2] = argv[4];
}

r_fd = (recv_socket *)calloc(1, sizeof(recv_socket));
s_fd = (send_socket *)calloc(1, sizeof(send_socket));
if(init_recv_sock(recv_ip_port) < 0){
return -1;
}

if(init_send_sock(send_ip_port) < 0){
return -1;
}
return 0;
}

int deinit_socket()
{
task_runing = 0;
deinit_recv_sock();
deinit_send_sock();
free(r_fd);
free(s_fd);
return 0;
}

int reinit()
{
deinit_socket();
init_socket(0, NULL);
return 0;
}

int num = 0;

int proc_msg()
{
char buf[1024];
int recv_len;
while(task_runing){
// sleep(1);
memset(buf, 0, sizeof(buf));
recv_len = recv_pock(r_fd, buf, 1024);
if(recv_len < 0){
reinit();
continue;
}
send_pock(s_fd, buf, recv_len);
// printf("3\n");
if((num++) >= 65535){
num = 0;
}
// printf("num = %d\n", num);
}
return 0;
}

int main(int argc, char *argv[])
{
int pid;
task_runing = 1;
if(argc < 5){
printf("arg too few!\n");
return -1;
}else if(atoi(argv[4]) != 1812 && atoi(argv[4]) != 1813){
printf("dst port is error!\n");
return -1;
}

if(init_socket(argc, argv) < 0){
return -1;
}
// printf("4\n");
// init_daemon();
// printf("1\n");

while(1){
pid = fork();
if(pid > 0){
wait(NULL);
}else if(pid < 0){
return -1;
}else{
proc_msg();
// printf("2\n");
break;
}
}

printf("exit!\n");
deinit_socket();
return -1;
}

...全文
153 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
zpzkitt 2013-12-06
  • 打赏
  • 举报
回复
发包程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <assert.h>
#include <netdb.h>
 
#include <signal.h>
#include <sys/param.h>
#include <sys/stat.h>
 
char buf[4096] = "0000 01ae 0000 0000 0000 0000 0000 0000\
04fc 01a2 0000 0000 0000 0000 0000 0000\
0000 0000 0113 3035 3135 3230 3031 3139\
3133 3340 766f 6405 0603 20e0 2b04 063d\
b1f8 3608 060a b965 0d0b 0576 6f64 1922\
3135 3732 3836 3430 3033 3134 3537 3238\
3135 3732 3836 3430 3033 3134 3537 3238\
201a 5943 2d4a 482d 3632 312d 4241 532d\
322e 4d41 4e2e 4d45 3630 2806 0000 0001\
2906 0000 0000 2c23 5943 2d4a 482d 3630\
3332 3134 3137 3132 3030 3034 3338 3138\
6132 3030 3337 3638 342d 0600 0000 0137\
0652 85b9 ef3d 0600 0000 0f1f 1364 303a\
3135 3a34 613a 6465 3a32 343a 3330 5732\
736c 6f74 3d33 3b73 7562 736c 6f74 3d32\
3b70 6f72 743d 3134 3b76 6c61 6e69 643d\
3433 3b76 6c61 6e69 6432 3d31 3731 323b\
0606 0000 0002 0706 0000 0001 4d09 3331\
3436 3030 3033 0600 0000 001c 0600 0000\
001b 0600 02a2 c41a 7b00 0007 db3c 2131\
302e 3138 352e 3130 312e 3133 2064 303a\
3135 3a34 613a 6465 3a32 343a 3330 0206\
0030 0110 0506 0030 0110 1606 0000 0005\
1a06 0000 9334 8a05 766f 6454 0600 0000\
003d 0600 0000 053e 0600 0000 0599 1364\
303a 3135 3a34 613a 6465 3a32 343a 3330\
9f06 0000 0000 0106 0047 d070 0406 0047\
d070";
char in_buf[1024] = {0};
#define HEX_NUM ()
 
int atoi_simp(char *ch)
{
    int a = 0, i = 0;
    for(i = 0;i < 2;i++){
        if(i == 0){
            if(ch[i] >= '0' && ch[i] <= '9'){
                a += ch[i] - '0';
            }else if(ch[i] >= 'a' && ch[i] <= 'f'){
                a += ch[i] - 87;
            }
        }else if(i == 1){
            if(ch[i] >= '0' && ch[i] <= '9'){
                a += (ch[i] - '0') * 16;
            }else if(ch[i] >= 'a' && ch[i] <= 'f'){
                a += (ch[i] - 87) * 16;
            }
        }
    }
    return a;
}
 
int ctoi()
{
    int num = 0, pos = 1;
    char buf_ch[2];
    char *tmp_buf = buf;
    while(*tmp_buf){
        if(!((*tmp_buf >= '0' && *tmp_buf <= '9') || (*tmp_buf >= 'a' && *tmp_buf <= 'f'))){
            tmp_buf++;
            continue;
        }
 
        if(pos > 1){
            printf("pos error!\n");
            return -1;
        }
         
        buf_ch[pos] = *tmp_buf;
        if((num % 2) == 1){
            in_buf[num / 2] = atoi_simp(buf_ch);
            pos = 1;
            num++;
            tmp_buf++;
            continue;
        }
         
        pos--;
        num++;
        tmp_buf++;
    }
    if(num % 2){
        printf("len error!\n");
        return -1;
    }
    return (num / 2);
}
 
int print_i()
{
    int i;
    for(i = 0;i < 434;i++){
        printf("%02x ", (unsigned char)in_buf[i]);
    }
    return 0;
}
 
int sock_create(unsigned short port)
{
    int fd;
    struct sockaddr_in inaddr;
 
    if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1 ) {
        printf("create socket error\n");
        return -1;
    }
 
    memset((void *)&inaddr, 0, sizeof(struct sockaddr_in));
    inaddr.sin_family      = AF_INET;
    inaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    inaddr.sin_port        = htons(port);
    if (bind(fd, (struct sockaddr*)&inaddr, sizeof(inaddr)) == -1) {
        close(fd);
        printf("bind socket failed!\n");
        return -1;
    }
     
    if (listen(fd, 5) == -1) {
        close(fd);
        return -1;
    }
 
 
    return fd;
}
 
int num = 0;
 
int send_simp_radius(unsigned short port)
{
    int sock_fd, cli_sock, len, ret;
    socklen_t cli_sock_len;
    struct sockaddr_in    cli_addr;
    cli_sock_len = sizeof(struct sockaddr_in);
     
    sock_fd = sock_create(port);
    if((len = ctoi()) < 0){
        printf("ctoi error\n");
        return -1;
    }
//    print_i();
//    printf("len = %d\n", len);
     
    while(1){
        cli_sock = accept(sock_fd, (struct sockaddr *)&cli_addr, &cli_sock_len);
        if(cli_sock < 0) {
            perror("accept:\n");
        }else{
        while(1){
                usleep(500);
    //            printf("aaadsffd\n");
                ret = send(cli_sock, in_buf, len, MSG_NOSIGNAL);
    //            print_i();
                if(ret != len){
                    printf("send error!\n");
                    break;
                }
                if((num++) >= 65535){
                    num = 0;
                }
                printf("num = %d\n", num);
            }
        }
    }
    return 0;
}
 
int main(int argc, char *argv[])
{
    if(argc != 2){
        printf("arg error!\n");
        return -1;
    }
     
    int port = atoi(argv[1]);
    send_simp_radius(port);
    return 0;
}
接受包 编译: gcc -o client recv_radius_tool.c 运行:./client 10.121.21.226 9002 10.121.21.161 1812 (4个参数发包ip,port,收包ip,port) 编译:gcc -o server simp_radius_server.c 运行:./server 9002 (指定发送的端口) 运行同时使用tcpdump -w radius.cap -i eth0抓包。

4,356

社区成员

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

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