- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
此 C 代码从套接字中提取 FreeBSD 系统上的源和目标 IPv4 地址。我将它移植到 Linux,但它只能部分工作。它正确地打印了 pk 的源地址,但没有打印 pk 的目标地址(这将是我机器的 IP 地址)。我总是得到 0.0.0.0
的目标地址。
如何更改代码以使其也提取/打印目标地址?
static void* start_controlpackets_demuxer_ipv4(void* arg) {
int r;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
struct addrinfo* sorter_addr;
r = getaddrinfo(NULL, LISP_CONTROL_PORT, &hints, &sorter_addr);
if (r != 0) {
fatalr("Unable to get westbound IPv4 listener address", r);
}
struct addrinfo* curr_addr;
int s;
for (curr_addr = sorter_addr; curr_addr != NULL; curr_addr = curr_addr->ai_next) {
s = socket(curr_addr->ai_family, curr_addr->ai_socktype, curr_addr->ai_protocol);
if (s == -1) {
continue;
}
r = bind(s, curr_addr->ai_addr, curr_addr->ai_addrlen);
if (r == -1) {
continue;
}
freeaddrinfo(sorter_addr);
break;
}
if (curr_addr == NULL) {
fatal("Unable to bind westbound IPv4 listener");
}
ipv4_controlpackets_socket = s;
debug_printf("IPv4 westbound server is listening");
/*
* The datagram is kept in the stack space. Should the processing be offloaded to a pool of worker threads,
* it will be necessary to move it to the heap.
*/
uint8_t buf[IP_MAXLEN];
char control_buf[SOCK_MSG_CONTROL_LEN];
int opt = 1;
setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt));
while (1) {
ipv4_datagram datagram;
datagram.payload = buf;
struct msghdr raw_msg;
struct iovec iov;
raw_msg.msg_name = &(datagram.source);
raw_msg.msg_namelen = sizeof(datagram.source);
raw_msg.msg_iov = &iov;
raw_msg.msg_iovlen = 1;
raw_msg.msg_iov->iov_base = datagram.payload;
raw_msg.msg_iov->iov_len = IP_MAXLEN;
raw_msg.msg_control = (caddr_t) &control_buf;
raw_msg.msg_controllen = SOCK_MSG_CONTROL_LEN;
raw_msg.msg_flags = 0;
datagram.payload_len = recvmsg(s, &raw_msg, 0);
if (datagram.payload_len < 0) {
fatal("Error reading from westbound IPv4 socket");
}
for (struct cmsghdr *c = CMSG_FIRSTHDR(&raw_msg); c != NULL; c = CMSG_NXTHDR(&raw_msg, c)) {
if (c->cmsg_level != IPPROTO_IP || c->cmsg_type != IP_RECVDSTADDR) {
continue;
}
struct in_addr* tmp_destination = (struct in_addr*) CMSG_DATA(c);
memset(&(datagram.destination), 0, sizeof(datagram.destination));
#ifndef LINUX_OS
datagram.destination.sin_len = sizeof(datagram.destination);
#endif
datagram.destination.sin_family = AF_INET;
datagram.destination.sin_addr = *tmp_destination;
}
char src[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(datagram.source.sin_addr), src, INET_ADDRSTRLEN);
char dst[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(datagram.destination.sin_addr), dst, INET_ADDRSTRLEN);
debug_printf("Processing UDPv4 datagram from %s to %s", src, dst);
process_ipv4_datagram(&datagram);
}
pthread_exit(0);
}
最佳答案
在 Linux 中,套接字选项是 IP_RECVORIGDSTADDR
. (您的代码也无法初始化 iov
。)
这是一个在 Linux 中运行的简单测试示例(如果使用 2.6.29、3.x 或更高版本的内核)。
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
typedef struct {
struct sockaddr_in source;
struct sockaddr_in destination;
uint8_t *payload;
int payload_len;
} ipv4_datagram;
void process_ipv4_datagram(ipv4_datagram *const datagram)
{
char src_host[128], src_port[32];
char dst_host[128], dst_port[32];
int result, i;
src_host[0] = src_port[0] = '\0';
dst_host[0] = dst_port[0] = '\0';
result = getnameinfo((const struct sockaddr *)(&datagram->source),
sizeof (struct sockaddr_in),
src_host, sizeof src_host,
src_port, sizeof src_port,
NI_NUMERICHOST | NI_NUMERICSERV);
if (result) {
fprintf(stderr, "Warning: Cannot translate source address: %s.\n", gai_strerror(result));
fflush(stderr);
}
result = getnameinfo((const struct sockaddr *)(&datagram->destination),
sizeof (struct sockaddr_in),
dst_host, sizeof dst_host,
dst_port, sizeof dst_port,
NI_NUMERICHOST | NI_NUMERICSERV);
if (result) {
fprintf(stderr, "Warning: Cannot translate destination address: %s.\n", gai_strerror(result));
fflush(stderr);
}
printf("Received %d bytes,\n", datagram->payload_len);
printf(" From %s port %s\n", src_host, src_port);
printf(" To %s port %s", dst_host, dst_port);
for (i = 0; i < datagram->payload_len; i++)
if (i & 15)
printf(" %02x", datagram->payload[i]);
else
printf("\n\t%02x", datagram->payload[i]);
printf("\n");
fflush(stdout);
}
static volatile sig_atomic_t done = 0;
static void handle_done(int signum)
{
__sync_bool_compare_and_swap(&done, (sig_atomic_t)0, (sig_atomic_t)signum);
}
static int install_done(int signum)
{
struct sigaction act;
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
act.sa_handler = handle_done;
act.sa_flags = 0;
if (sigaction(signum, &act, NULL) == -1)
return errno;
return 0;
}
int main(int argc, char *argv[])
{
int socketfd = -1;
/* Verify command line parameters, and print usage if necessary.
*/
if (argc < 2 || argc > 3 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [ -h | --help ]\n", argv[0]);
fprintf(stderr, " %s [ ADDRESS/HOST ] PORT\n", argv[0]);
fprintf(stderr, "\n");
fprintf(stderr, "This listens on IPv4 UDP connections, and reports on them.\n");
fprintf(stderr, "Send INT (Ctrl+C), HUP, or TERM signal to exit.\n");
fprintf(stderr, "\n");
return EXIT_FAILURE;
}
/* Install INT, TERM, and HUP signal handlers.
* They all set the 'done' flag if caught.
*/
if (install_done(SIGINT) ||
install_done(SIGTERM) ||
install_done(SIGHUP)) {
fprintf(stderr, "Cannot install signal handlers: %s.\n", strerror(errno));
return EXIT_FAILURE;
}
/* Open the listening socket. */
{
struct addrinfo *list = NULL, *curr, hints;
const char *node, *serv;
int result;
/* Empty or "-" or "*" address is the wildcard address. */
if (argc == 3) {
node = argv[1];
serv = argv[2];
if (node[0] == '\0' || !strcmp(node, "-") || !strcmp(node, "*"))
node = NULL;
} else {
node = NULL;
serv = argv[1];
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
result = getaddrinfo(node, serv, &hints, &list);
if (result) {
if (node)
fprintf(stderr, "%s %s: %s.\n", node, serv, gai_strerror(result));
else
fprintf(stderr, "%s: %s.\n", serv, gai_strerror(result));
return EXIT_FAILURE;
}
result = 0;
socketfd = -1;
for (curr = list; curr != NULL; curr = curr->ai_next) {
socketfd = socket(curr->ai_family, curr->ai_socktype, curr->ai_protocol);
if (socketfd == -1)
continue;
if (bind(socketfd, curr->ai_addr, curr->ai_addrlen) == 0)
break;
result = errno;
close(socketfd);
socketfd = -1;
}
freeaddrinfo(list);
if (socketfd == -1) {
if (result)
fprintf(stderr, "%s.\n", strerror(result));
else
fprintf(stderr, "Cannot bind to socket.\n");
return EXIT_FAILURE;
}
}
/* Enable the IP_RECVORIGDSTADDR socket option. */
{
int flag = 1;
if (setsockopt(socketfd, IPPROTO_IP, IP_RECVORIGDSTADDR, &flag, sizeof flag) == -1) {
fprintf(stderr, "IP_RECVORIGDSTADDR not supported: %s.\n", strerror(errno));
close(socketfd);
return EXIT_FAILURE;
}
}
/* Receive datagram messages, until signaled.
* Note that signal delivery causes recvmsg() to return with -1, errno == EINTR.
*/
while (!done) {
char data_buffer[1024];
char ancillary_buffer[1024];
ssize_t data_bytes;
ipv4_datagram dgram;
struct msghdr msg;
struct iovec iov;
struct cmsghdr *cmsg;
iov.iov_base = data_buffer;
iov.iov_len = sizeof data_buffer;
msg.msg_name = &(dgram.source);
msg.msg_namelen = sizeof dgram.source;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = ancillary_buffer;
msg.msg_controllen = sizeof ancillary_buffer;
msg.msg_flags = 0;
memset(&(dgram.source), 0, sizeof dgram.source);
memset(&(dgram.destination), 0, sizeof dgram.destination);
data_bytes = recvmsg(socketfd, &msg, 0);
if (data_bytes == (ssize_t)-1) {
/* Interrupted by a signal? */
if (errno == EINTR)
continue;
/* Other errors we can ignore? */
if (errno == EAGAIN || errno == EWOULDBLOCK ||
errno == ECONNREFUSED)
continue;
fprintf(stderr, "Error receiving data: %s.\n", strerror(errno));
fflush(stderr);
break;
}
dgram.payload = (void *)data_buffer;
dgram.payload_len = data_bytes;
/* Find IP_ORIGDSTADDR ancillary message. */
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))
if (cmsg->cmsg_level == IPPROTO_IP &&
cmsg->cmsg_type == IP_ORIGDSTADDR)
memmove(&dgram.destination, CMSG_DATA(cmsg), sizeof dgram.destination);
process_ipv4_datagram(&dgram);
}
close(socketfd);
return EXIT_SUCCESS;
}
这是一个编辑版本,用于说明所需的 ipv4_datagram
结构和 process_ipv4_datagram()
函数的用法。
使用例如编译它
gcc -Wall -Wextra -O2 example.c -o example
如果你运行例如
./example host port
您可以使用 Ctrl+C 来指示它干净地退出。使用例如netcat 使用例如测试连接(来自同一本地网络上的其他机器)
date | nc -q 1 -u host port
关于c - 我将代码从 FreeBSD 移植到 Linux,但它没有提取目标地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34766075/
我正在做一个业余爱好项目,使用 Ruby、PHP 或 Java 来抓取 ASP.net 网站的内容。例如,如果网站 url“www.myaspnet.com/home.aspx”。我想从 home.a
如果我有这些字符串: mystrings <- c("X2/D2/F4", "X10/D9/F4", "X3/D22/F4",
我有以下数据集 > head(names$SAMPLE_ID) [1] "Bacteria|Proteobacteria|Gammaproteobacteria|Pseudomonadales|Mor
设置: 3个域类A,B和C。A和B在插件中。 C在依赖于此插件的应用程序中。 class A{ B b static mapping = { b fetch: 'joi
我不知道如何提取 XML 文件中的开始标记元素名称。我很接近〜意味着没有错误,我正在获取标签名称,但我正在获取标签名称加上信息。我得到的是: {http://www.publishing.org}au
我有一个字符串 x <- "Name of the Student? Michael Sneider" 我想从中提取“Michael Sneider”。 我用过: str_extract_all(x,
我有一个如下所示的文本文件: [* content I want *] [ more content ] 我想读取该文件并能够提取我想要的内容。我能做的最好的事情如下,但它会返回 [更多内容] 请注意
假设我有一个项目集合 $collection = array( 'item1' => array( 'post' => $post, 'ca
我正在寻找一种过滤文本文件的方法。我有许多文件夹名称,其中包含许多文本文件,文本文件有几个没有人员,每个人员有 10 个群集/组(我在这里只显示了 3 个)。但是每个组/簇可能包含几个原语(我在这里展
我已经编写了一个从某个网页中提取网址的代码,我面临的问题是它不会以网页上相同的方式提取网址,我的意思是如果该网址位于某些网页中法语,它不会按原样提取它。我该如何解决这个问题? import reque
如何在 C# 中提取 ZipFile?(ZipFile 是包含文件和目录) 最佳答案 为此使用工具。类似于 SharpZip .据我所知 - .NET 不支持开箱即用的 ZIP 文件。 来自 here
我有一个表达: [training_width]:lofmimics 我要提取[]之间的内容,在上面的例子中我要 training_width 我试过以下方法: QRegularExpression
我正在尝试创建一个 Bash 脚本,该脚本将从命令行给出的最后一个参数提取到一个变量中以供其他地方使用。这是我正在处理的脚本: #!/bin/bash # compact - archive and
我正在寻找一个 JavaScript 函数/正则表达式来从 URI 中提取 *.com...(在客户端完成) 它应该适用于以下情况: siphone.com = siphone.com qwr.sip
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
编辑:添加了实际的 JSON 对象和代码以供审查 我有这种格式的 JSON(只是这种层次结构,假设 JSON 正常工作) {u'kind': u'calendar#events', u'default
我已经编写了代码来使用 BeautifulSoup 提取一本书的 url 和标题来自页面。 但它并没有在 > 之间提取惊人的 super 科学故事 1930 年 4 月这本书的名字。和 标签。 如何提
使用 Java,我想提取美元符号 $ 之间的单词。 例如: String = " this is first attribute $color$. this is the second attribu
您好,我正在尝试找到一种方法来确定字符串中的常量,然后提取该常量左侧的一定数量的字符。 例如-我有一个 .txt 文件,在那个文件的某处有数字 00nnn 数字的例子是 00234 00765 ...
php读取zip文件(删除文件,提取文件,增加文件)实例 从zip压缩文件中提取文件 复制代码 代码如下: <?php /* php 从zip压缩文件
我是一名优秀的程序员,十分优秀!