我有一些用SOCK_RAW socket发送tcp包的代码。我的程序只接受一个参数:主机名
以下是程序工作原理的说明:

getaddrinfo(argv[1], NULL, hints, &answ) //argv[1] it is host name
....
....
socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol) //tmp = answ->ai_next
....
....
/* filling the tcphdr struct */
send_frame->source = s_port;
send_frame->dest = d_port;
send_frame->seq = seq_num;
send_frame->ack_seq = ack_num;
send_frame->doff = 5;
send_frame->fin = 0;
send_frame->syn = 1;
send_frame->rst = 0;
send_frame->psh = 0;
send_frame->ack = 0;
send_frame->urg = 0;
send_frame->window = 0xffff;
send_frame->check = 0;
/* in this part I form a pseudo tcp header for checksum */
/* but for pseudo header i need a source ip address */
/* but I can not know before, what will be the source address */
/* and I can not form the pseudo header, because I do not know what my source address */
sendto(sock, send_frame, sizeof(struct tcphdr), 0, tmp->ai_addr, tmp->ai_addrlen);

在评论中,我解释了这个问题,要求清楚:我如何确定我的源ip地址,这将取决于我发送包的位置。我不想输入设备的程序名,它可能是tun0和wlan0以及我的自定义网络接口。是否有一个简单的机制来查找src地址,只知道目的地?
我立即认为有必要对路由表进行分析,但是如果存在这样的方式,我需要一个更简单的方法。
我找到了答案:
    connect(sock, tmp->ai_addr, tmp->ai_addrlen);
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);
    getsockname(sock, (struct sockaddr *)&addr, &len);
    printf("%s\n", inet_ntoa(addr.sin_addr));

如果这个问题是有意义的,就更不用说了,如果不是,就可以把它去掉

最佳答案

我找到了答案:

    connect(sock, tmp->ai_addr, tmp->ai_addrlen);
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);
    getsockname(sock, (struct sockaddr *)&addr, &len);
    printf("%s\n", inet_ntoa(addr.sin_addr));

——伊万·伊万诺维奇

10-07 12:51