【发布时间】:2015-02-09 07:23:53
【问题描述】:
我有一些使用 SOCK_RAW 套接字发送 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);
在 cmets 中,我解释了问题,要求澄清:如何确定我的源 IP 地址,这取决于我发送包裹的位置。我不想放我设备的程序名称,可能是 tun0 和 wlan0 和 My_Custom_Net_Interface_0012。是否有一种简单的机制来查找 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));
如果这个问题感兴趣,可以不考虑,如果不感兴趣,可以删除
【问题讨论】:
-
你能更清楚你想要什么吗?在您的标题中,您要求提供接口名称。但在问题中,您要求的是源 IP 地址。
-
不,我想我需要一个名字来获得地址,但我能够获得一个没有名字的地址。这可以通过函数来完成:connect()getsockname(),当然这只适用于:socket()
-
如果需要获取接口名称,可以使用
getifaddrs()。或者你可以阅读this question,有几个答案。
标签: c sockets network-programming