Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用UDP将套接字绑定到特定接口?-C_C_Sockets - Fatal编程技术网

使用UDP将套接字绑定到特定接口?-C

使用UDP将套接字绑定到特定接口?-C,c,sockets,C,Sockets,我想知道如何将套接字绑定到C中的特定接口 My@IP是X.Y.Z.3,网关是eth1上的X.Y.Z.1 但是如果我发送数据包,它将通过环回接口发送 奇怪的是,如果我使用X.Y.Z.9(例如)作为IP源(而不是我的)制作数据包,它就可以工作 有线索吗 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #include <sys/ioct

我想知道如何将套接字绑定到C中的特定接口

My@IP是X.Y.Z.3,网关是eth1上的X.Y.Z.1 但是如果我发送数据包,它将通过环回接口发送

奇怪的是,如果我使用X.Y.Z.9(例如)作为IP源(而不是我的)制作数据包,它就可以工作

有线索吗

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/time.h>

#define PCK_MAX_LEN  1024

#define IP_NAMESERV "172.20.10.1"
#define IP_ATTACKER "172.20.10.3"

#define PORT_QUERY   5555

pthread_cond_t ans_listen = PTHREAD_COND_INITIALIZER;
pthread_cond_t ans_receiv = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *fctThreadSendQuery      (void *arg); // Send 1 query to random.example.com
void *fctThreadListenResponse (void *arg); // Listen for response to that query

int main (void)
{
  pthread_t threadSendQuery;
  pthread_t threadListenResponse;

  pthread_create (&threadSendQuery, NULL, fctThreadSendQuery, NULL);
  pthread_create (&threadListenResponse, NULL, fctThreadListenResponse, NULL);

  pthread_join (threadListenResponse, NULL);
  pthread_join (threadSendQuery, NULL);

  return 0;
}


void *fctThreadSendQuery(void *arg) {
  unsigned int nQuery = 1;

  struct sockaddr_in *sin_attacker, *sin_resolver;
  sin_attacker = calloc(1, sizeof(struct sockaddr_in));
  sin_resolver = calloc(1, sizeof(struct sockaddr_in));

  sin_attacker->sin_family = AF_INET;
  sin_attacker->sin_addr.s_addr = inet_addr(IP_ATTACKER);
  sin_attacker->sin_port = htons(PORT_QUERY);

  int fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

  bind(fd, sin_attacker, sizeof(struct sockaddr_in));

  sin_resolver->sin_family = AF_INET;
  sin_resolver->sin_addr.s_addr = inet_addr(IP_RESOLVER);
  sin_resolver->sin_port = htons(53);

  while (1) {
    // Now, we can build and send the query
    char *packet = calloc(PCK_MAX_LEN, sizeof(char));
    int pck_len = 0;
    int id = 0;

    char *target = calloc(16, sizeof(char));
    strcpy(target, randomTarget(nQuery-1));
    build_packet(IP_SRC, IP_DST, PORT_QUERY, 53, packet, &pck_len, target, NAME_LEN, id, QUERY);

    // Before sending the packet, we want to be sure that fctThreadListenResponse is listening
    pthread_mutex_lock (&mutex);
    puts("SEND: wait for RECV to LISTEN");
    pthread_cond_wait (&ans_listen, &mutex);
    puts("SEND: wait for RECV to LISTEN - OK");
    pthread_mutex_unlock(&mutex);
    sendto (fd, packet, pck_len, 0, sin_attacker, sizeof(struct sockaddr_in));
    puts("SEND: PCK SENT");

    pthread_mutex_lock (&mutex);
    puts("SEND: wait for RECV to RECV");
    pthread_cond_wait (&ans_receiv, &mutex);
    puts("SEND: wait for RECV to RECV - OK");
    pthread_mutex_unlock(&mutex);

    nQuery++;
    free(target);
    free(packet);
  }

  free(sin_resolver);
  free(sin_attacker);
  pthread_exit(NULL);
}

void *fctThreadListenResponse (void *arg) {
  usleep(100);
  struct sockaddr_in *sin_attacker, *sin_resolver;
  sin_attacker = calloc(1, sizeof(struct sockaddr_in));
  sin_resolver = calloc(1, sizeof(struct sockaddr_in));

  sin_attacker->sin_family = AF_INET;
  sin_attacker->sin_addr.s_addr = inet_addr(IP_ATTACKER);
  sin_attacker->sin_port = htons(PORT_QUERY);

  int fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

  bind(fd, sin_attacker, sizeof(struct sockaddr_in));

  while (1) {
    char *packet = calloc(PCK_MAX_LEN, sizeof(char));
    unsigned int pck_len;

    pthread_mutex_lock (&mutex);
    pthread_cond_signal (&ans_listen);
    puts("RECV: LISTENING");
    pthread_mutex_unlock(&mutex);

    pck_len = recvfrom(fd, packet, PCK_MAX_LEN, 0, NULL, sin_resolver);
    puts("RECV: PCK RECEIVED");

    if (pck_len > 0) {
      pthread_mutex_lock (&mutex);
      pthread_cond_signal (&ans_receiv);
      pthread_mutex_unlock (&mutex);
    }

    free(packet);
  }
  pthread_exit(NULL);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义PCK_MAX_LEN 1024
#定义IP_名称服务“172.20.10.1”
#定义IP_攻击者“172.20.10.3”
#定义端口查询5555
pthread_cond_t ans_listen=pthread_cond_初始值设定项;
pthread_cond_t ans_receiv=pthread_cond_初始值设定项;
pthread\u mutex\u t mutex=pthread\u mutex\u初始值设定项;
void*fctThreadSendQuery(void*arg);//向random.example.com发送1个查询
void*fctThreadListenResponse(void*arg);//倾听对该问题的回答
内部主(空)
{
pthread\u t threadSendQuery;
pthread_t threadListenResponse;
pthread_create(&threadSendQuery,NULL,fctThreadSendQuery,NULL);
pthread_create(&threadListenResponse,NULL,fctthreadslistenresponse,NULL);
pthread_join(threadListenResponse,NULL);
pthread_join(threadSendQuery,NULL);
返回0;
}
void*fctThreadSendQuery(void*arg){
无符号整数=1;
*sin\u攻击者,*sin\u解析器中的结构sockaddr\u;
sin_攻击者=calloc(1,sizeof(struct sockaddr_in));
sin_resolver=calloc(1,sizeof(struct sockaddr_in));
sin\u攻击者->sin\u家庭=家庭;
sin\u攻击者->sin\u addr.s\u addr=inet\u addr(IP\u攻击者);
sin\u攻击者->sin\u port=htons(port\u查询);
int fd=插座(AF_INET、SOCK_RAW、IPPROTO_RAW);
绑定(fd,sin_攻击者,sizeof(struct sockaddr_in));
sin\u解析器->sin\u系列=AF\u INET;
sin\u解析器->sin\u addr.s\u addr=inet\u addr(IP\u解析器);
sin_解析器->sin_端口=htons(53);
而(1){
//现在,我们可以构建并发送查询
char*packet=calloc(PCK_MAX_LEN,sizeof(char));
int pck_len=0;
int id=0;
char*target=calloc(16,sizeof(char));
strcpy(靶标,随机靶标(nQuery-1));
构建数据包(IP_SRC、IP_DST、端口查询、53、数据包和pck长度、目标、名称长度、id、查询);
//在发送数据包之前,我们要确保fctThreadListenResponse正在侦听
pthread_mutex_lock(&mutex);
puts(“发送:等待RECV收听”);
pthread_cond_wait(&ans_listen,&mutex);
puts(“发送:等待RECV侦听-确定”);
pthread_mutex_unlock(&mutex);
sendto(fd,packet,pck_len,0,sin_攻击者,sizeof(struct sockaddr_in));
看跌期权(“发送:PCK发送”);
pthread_mutex_lock(&mutex);
puts(“发送:等待RECV到RECV”);
pthread_cond_wait(&ans_receiv,&mutex);
puts(“发送:等待RECV到RECV-确定”);
pthread_mutex_unlock(&mutex);
nQuery++;
自由(目标);
免费(包);
}
自由(sin_解析器);
免费(sin_攻击者);
pthread_exit(NULL);
}
void*fctthreadsistenresponse(void*arg){
usleep(100);
*sin\u攻击者,*sin\u解析器中的结构sockaddr\u;
sin_攻击者=calloc(1,sizeof(struct sockaddr_in));
sin_resolver=calloc(1,sizeof(struct sockaddr_in));
sin\u攻击者->sin\u家庭=家庭;
sin\u攻击者->sin\u addr.s\u addr=inet\u addr(IP\u攻击者);
sin\u攻击者->sin\u port=htons(port\u查询);
int fd=插座(AF_INET、SOCK_RAW、IPPROTO_RAW);
绑定(fd,sin_攻击者,sizeof(struct sockaddr_in));
而(1){
char*packet=calloc(PCK_MAX_LEN,sizeof(char));
无符号整数pck_len;
pthread_mutex_lock(&mutex);
pthread_cond_信号(&ans_listen);
看跌期权(“记录:倾听”);
pthread_mutex_unlock(&mutex);
pck_len=recvfrom(fd,packet,pck_MAX_len,0,NULL,sin_解析器);
看跌期权(“RECV:PCK已收到”);
如果(pck_len>0){
pthread_mutex_lock(&mutex);
pthread_cond_信号(&ans_receiv);
pthread_mutex_unlock(&mutex);
}
免费(包);
}
pthread_exit(NULL);
}

我不知道build_数据包是做什么的,但是sendto的文档只列出了几个可能的原型,其中只有一个有您正在使用的参数列表:

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);
您在通话中使用:

sendto (fd, packet, pck_len, 0, sin_attacker, sizeof(struct sockaddr_in));

您已经使用IP\U攻击者配置了sin\U攻击者(dest\u addr参数),这似乎是您自己的地址。因此,sendto会看到本地系统上承载的目标地址,并使用环回适配器发送数据包。

当然,您可以使用
bind()
函数来执行此操作。你一定是通过环回接口给自己发送的,这有什么不对?我不是给自己发送的。我要把它送到网关。我尝试了一些我发现的东西(SO_BINDTODEVICE,…),但似乎没有任何效果。为什么是原始插座?如果您想使用UDP(如您所述),SOCK_DGRAM和IPPROTO_UDP可能更合适