我一直在用C编写一些套接字代码.我需要修改数据包头并控制它们的发送方式,所以我采用了原始套接字方法.但是,我写的代码不能在BSD系统上编译(Mac OS X/Darwin,FreeBSD等)
我已经对此进行了大量研究,并发现BSD系统无法像Linux(甚至Windows)那样处理原始套接字.从我读过的内容来看,似乎我需要使用bpf(berkley数据包过滤器),但我无法弄清楚bpf是如何工作的,或者我将如何使用原始套接字.
如果有人能对这一点有所了解,我会非常兴奋:D
PS我甚至会对一些显示如何在BSD环境中处理原始套接字的源代码感到满意.它不一定是指导或解释.我只想看看它是如何工作的.
在符合C99的C中,假设没有预处理器宏定义,这是设置无符号整数的最大值的更便携方式:
unsigned x = -1;
Run Code Online (Sandbox Code Playgroud)
要么
unsigned y = ~0;
Run Code Online (Sandbox Code Playgroud)
我记得几年前我遇到了一个线程,声称将unsigned int设置-1为更加便携,因为在隐藏的系统上~0有某种陷阱表示 ; 我不再觉得这是真的.
我知道在C99标准(即模数值等)中很好地定义了将无效值设置为无符号变量的行为,但是反转怎么样0呢?
此外,如果两个操作都是同等可移植的,并且假设没有编译器优化,哪个操作在时钟周期方面会更有效?
对于我的论文,我使用ARAN协议创建一个Manet.要安装协议我正在使用本手册,但第一步,创建trace_route,我收到的错误如:
-linux/module.h: No such file or directory
-linux/procs_Fs: No such file or directory
-linux/skbuff: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我搜索了网络,发现问题出在标题中,但我找不到解决方案......
PS我正在使用Ubuntu 10.04 LTS Kernel 2.6.33重新编译
我正试图找到一种方法来使枚举"无符号".
enum{
x1 = 0,
x2,
x3
};
uint8_t = x2; /* <--- PC-LINT MISRA-C 2004 will complain about mixing signed and unsigned here */
Run Code Online (Sandbox Code Playgroud)
当然,我可以添加一个类型转换来摆脱错误,这是耗时且容易出错的.
uint8_t = (uint8_t)x2; /* This works, but is a lot of extra work over the course of 1000s of lines of code*/
Run Code Online (Sandbox Code Playgroud)
那么,有没有办法让MISRA-C 2004想要的特定枚举无符号?
我正在尝试找到unistd.h头文件中声明的Unix函数的Linux 3.2.21 x86_64实现.看看Linux unistd.h产生这个原型:sync(2)
/* Make all changes done to all files actually appear on disk. */
extern void sync (void) __THROW;
Run Code Online (Sandbox Code Playgroud)
所以我认为这sync是在Linux内核之外定义并查看glibc 2.7内部的内容,它在glibc-2.17/misc/sync.c中给我这个定义:
/* Make all changes done to all files actually appear on disk. */
void
sync ()
{
__set_errno (ENOSYS);
}
Run Code Online (Sandbox Code Playgroud)
所以这意味着sync除了设置值之外别无其他errno.
但是,当我在系统上反汇编/usr/lib/x86_64-linux-gnu/libc.a时,我发现同步部分进行系统调用,传递值162(所以它正在做某事).
再次在arch/x86/include/asm/unistd_64.h中查看Linux源代码,我看到:
#define __NR_sync 162
__SYSCALL(__NR_sync, sys_sync)
Run Code Online (Sandbox Code Playgroud)
现在我真的很困惑.
如果sync(2)在Linux之外定义,为什么有系统调用呢? …
我很难理解何时应该编写设备驱动程序,而不是仅仅通过outb我的用户空间程序将操作码直接发送到硬件.我最初认为我应该为硬件创建简单的例程,但现在我开始认为算法应该保留在用户空间中.
假设我正在编程一个假想的机器人手臂.我可以在Linux内核模块中编写几个函数,这些函数可以自动执行常见任务所需的硬件输出(例如,将arm移动到HOME位置,从装配线开始处的已知位置拾取新块等).但是,在阅读了有关设备驱动程序的更多信息之后,似乎经验法则是尽可能使设备驱动程序尽可能接近特定于硬件的代码,从而将"繁重的"算法留给用户空间.
这让我感到困惑,因为如果设备驱动程序实现的唯一函数是简单的操作码调用,那么用户空间程序使用设备文件而不是直接调用outb/ 的原因是什么inb?
我想我想弄清楚的是:我如何决定内核空间而不是用户空间中的功能?
在atexit图书馆等大型项目中使用是否存在固有的危险?
如果是这样,那背后的技术性质atexit可能会导致大型项目出现问题?
假设有一个端口映射的I/O设备,它可以在IRQ线上任意产生中断.可以通过outb对特定寄存器的单次调用来清除设备的待处理中断.
此外,假设通过以下方式将跟随中断处理程序分配给相关的IRQ线request_irq:
irqreturn_t handler(int irq, void *data)
{
/* clear pending IRQ on device */
outb(0, CLEAR_IRQ_REGISTER_ADDR);
/* device may generate another IRQ at this point,
* but this handler function has not yet returned */
/* signal kernel that IRQ has been handled */
return IRQ_HANDLED;
}
Run Code Online (Sandbox Code Playgroud)
这个IRQ处理程序中是否存在固有的竞争条件?例如,如果设备在"清除IRQ" outb调用之后但在handler函数返回之前生成另一个中断IRQ_HANDLED,会发生什么?
我可以想到三种情况:
handler返回后,Linux内核立即再次执行,以便处理第二个中断.handler第二次调用handler.linux interrupt race-condition linux-kernel interrupt-handling
我很难理解何时在扩展GCC内联汇编中使用特定输入操作数约束而不是另一个.
例如:
int x = 42;
asm("movl %0, %%eax;"
: /* no outputs */
: "r"(x)
: "%eax");
Run Code Online (Sandbox Code Playgroud)
我知道"r"告诉编译器使用寄存器保持的值x,但什么时候使用"g"或更合适"m"呢?"m"因为我正在使用寄存器目的地,所以会使用破坏此代码; 并且"g"对操作数约束过于"模糊"?
有符号整数在x86上通过二进制补码表示,其中符号位具有该值-(2^N).这导致在-2^N和2^N - 1(例如-32768通过32767)之间的典型可表示值范围.
我很好奇如果我在我的系统上取最小有符号整数值并乘以它以-1试图"强制"一个大于我系统上有符号整数的最大可表示值的最大值,会发生什么.
#include <stdio.h>
#include <limits.h>
int main(void){
signed int x, y;
x = INT_MIN;
y = x * -1;
printf("%d\n%d\n", x, y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这导致以下输出:
# gcc -std=c89 -pedantic int_min_test.c
# ./a.out
-2147483648
-2147483648
Run Code Online (Sandbox Code Playgroud)
我期待一个整数溢出(导致典型的值翻转),但看起来似乎没有关于xwith 的乘法操作-1.
在x86中是否INT_MIN与-1no-op 相乘?