确定是否有ipv4或ipv6数据结构

时间:2015-07-05 16:53:50

标签: c struct linux-kernel kernel kernel-module

在内核模块中,如果struct sockaddr sa_family初始化为AF_UNSPEC,我如何可靠地确定它是struct sockaddr_in还是struct sockaddr_in6?在Linux 3.16.0-4-686-pae(x86)上。

    struct sockaddr {
                        unsigned short     sa_family; // AF_UNSPEC
                        char               sa_data[14]; // ?
                        };
    struct sockaddr_in {
                        unsigned short     sin_family;
                        unsigned short     sin_port;
                        struct in_addr     sin_addr;
                        char               sin_zero[8];
                        };
    struct sockaddr_in6 {
                        unsigned short     sin6_family;
                        unsigned short     sin6_port;
                        unsigned int       sin6_flowinfo;
                        struct in6_addr    sin6_addr;
                        unsigned int       sin6_scope_id;
                        };

1 个答案:

答案 0 :(得分:2)

通常,当某些内容调用内核并提供CoreFoundation`__CFTypeCollectionRetain: 0x7fff8e2c2480 <+0>: pushq %rbp 0x7fff8e2c2481 <+1>: movq %rsp, %rbp 0x7fff8e2c2484 <+4>: pushq %r14 0x7fff8e2c2486 <+6>: pushq %rbx 0x7fff8e2c2487 <+7>: movq %rsi, %rbx 0x7fff8e2c248a <+10>: testq %rbx, %rbx 0x7fff8e2c248d <+13>: je 0x7fff8e2c25ae ; <+302> 0x7fff8e2c2493 <+19>: cmpb $0x0, -0x17f41f28(%rip) ; __CFDeallocateZombies 0x7fff8e2c249a <+26>: je 0x7fff8e2c257c ; <+252> 0x7fff8e2c24a0 <+32>: testq %rdi, %rdi 0x7fff8e2c24a3 <+35>: je 0x7fff8e2c24b5 ; <+53> 0x7fff8e2c24a5 <+37>: leaq -0x17f917cc(%rip), %rax ; kCFAllocatorSystemDefault 0x7fff8e2c24ac <+44>: cmpq %rdi, (%rax) 0x7fff8e2c24af <+47>: jne 0x7fff8e2c257c ; <+252> 0x7fff8e2c24b5 <+53>: testb $0x1, %bl 0x7fff8e2c24b8 <+56>: je 0x7fff8e2c24e4 ; <+100> 0x7fff8e2c24ba <+58>: movl %ebx, %eax 0x7fff8e2c24bc <+60>: shrl %eax 0x7fff8e2c24be <+62>: andl $0x7, %eax 0x7fff8e2c24c1 <+65>: cmpl $0x6, %eax 0x7fff8e2c24c4 <+68>: ja 0x7fff8e2c259c ; <+284> 0x7fff8e2c24ca <+74>: leaq 0xef(%rip), %rcx ; <+320> 0x7fff8e2c24d1 <+81>: movslq (%rcx,%rax,4), %rax 0x7fff8e2c24d5 <+85>: addq %rcx, %rax 0x7fff8e2c24d8 <+88>: jmpq *%rax 0x7fff8e2c24da <+90>: callq 0x7fff8e2df7b0 ; CFStringGetTypeID 0x7fff8e2c24df <+95>: jmp 0x7fff8e2c2594 ; <+276> 0x7fff8e2c24e4 <+100>: movl 0x8(%rbx), %eax 0x7fff8e2c24e7 <+103>: shrl $0x8, %eax 0x7fff8e2c24ea <+106>: andl $0x3ff, %eax 0x7fff8e2c24ef <+111>: movq (%rbx), %rcx 0x7fff8e2c24f2 <+114>: testq %rcx, %rcx 0x7fff8e2c24f5 <+117>: je 0x7fff8e2c2522 ; <+162> 0x7fff8e2c24f7 <+119>: cmpq -0x17f41f96(%rip), %rcx ; __CFConstantStringClassReferencePtr 0x7fff8e2c24fe <+126>: je 0x7fff8e2c2522 ; <+162> 0x7fff8e2c2500 <+128>: leaq -0x17f43fa7(%rip), %rdx ; __CFRuntimeObjCClassTable 0x7fff8e2c2507 <+135>: movq (%rdx,%rax,8), %r14 0x7fff8e2c250b <+139>: cmpq %r14, %rcx 0x7fff8e2c250e <+142>: je 0x7fff8e2c2522 ; <+162> 0x7fff8e2c2510 <+144>: testb $0x1, %cl 0x7fff8e2c2513 <+147>: je 0x7fff8e2c2594 ; <+276> 0x7fff8e2c2515 <+149>: movq %rbx, %rdi 0x7fff8e2c2518 <+152>: callq 0x7fff8e481b6a ; symbol stub for: object_getClass 0x7fff8e2c251d <+157>: cmpq %r14, %rax 0x7fff8e2c2520 <+160>: jne 0x7fff8e2c2594 ; <+276> 0x7fff8e2c2522 <+162>: callq 0x7fff8e481aaa ; symbol stub for: objc_collectableZone 0x7fff8e2c2527 <+167>: movq %rax, %rdi 0x7fff8e2c252a <+170>: movq %rbx, %rsi 0x7fff8e2c252d <+173>: callq 0x7fff8e481594 ; symbol stub for: auto_zone_is_valid_pointer 0x7fff8e2c2532 <+178>: testl %eax, %eax 0x7fff8e2c2534 <+180>: je 0x7fff8e2c255b ; <+219> 0x7fff8e2c2536 <+182>: movl 0x8(%rbx), %eax 0x7fff8e2c2539 <+185>: shrl $0x8, %eax 0x7fff8e2c253c <+188>: andl $0x3ff, %eax 0x7fff8e2c2541 <+193>: leaq -0x17f45ff8(%rip), %rcx ; __CFRuntimeClassTable 0x7fff8e2c2548 <+200>: movq (%rcx,%rax,8), %rax 0x7fff8e2c254c <+204>: testb $0x4, (%rax) 0x7fff8e2c254f <+207>: je 0x7fff8e2c2594 ; <+276> 0x7fff8e2c2551 <+209>: movq %rbx, %rdi 0x7fff8e2c2554 <+212>: callq 0x7fff8e2bf500 ; CFRetain 0x7fff8e2c2559 <+217>: jmp 0x7fff8e2c2594 ; <+276> 0x7fff8e2c255b <+219>: cmpl $0x0, 0xc(%rbx) 0x7fff8e2c255f <+223>: je 0x7fff8e2c2594 ; <+276> 0x7fff8e2c2561 <+225>: leaq -0x17f72248(%rip), %rsi ; @"storing a non-GC object %p in a GC collection, break on CFCollection_non_gc_storage_error to debug." 0x7fff8e2c2568 <+232>: movl $0x4, %edi 0x7fff8e2c256d <+237>: xorl %eax, %eax 0x7fff8e2c256f <+239>: movq %rbx, %rdx 0x7fff8e2c2572 <+242>: callq 0x7fff8e3b61e0 ; CFLog 0x7fff8e2c2577 <+247>: callq 0x7fff8e3c3290 ; CFCollection_non_gc_storage_error 0x7fff8e2c257c <+252>: movq %rbx, %rdi 0x7fff8e2c257f <+255>: popq %rbx 0x7fff8e2c2580 <+256>: popq %r14 0x7fff8e2c2582 <+258>: popq %rbp 0x7fff8e2c2583 <+259>: jmp 0x7fff8e2bf500 ; CFRetain 0x7fff8e2c2588 <+264>: callq 0x7fff8e2df7f0 ; CFNumberGetTypeID 0x7fff8e2c258d <+269>: jmp 0x7fff8e2c2594 ; <+276> 0x7fff8e2c258f <+271>: callq 0x7fff8e2df850 ; CFDateGetTypeID 0x7fff8e2c2594 <+276>: movq %rbx, %rax 0x7fff8e2c2597 <+279>: popq %rbx 0x7fff8e2c2598 <+280>: popq %r14 0x7fff8e2c259a <+282>: popq %rbp 0x7fff8e2c259b <+283>: retq 0x7fff8e2c259c <+284>: int3 0x7fff8e2c259d <+285>: callq 0x7fff8e482020 ; symbol stub for: getpid 0x7fff8e2c25a2 <+290>: movl $0x9, %esi 0x7fff8e2c25a7 <+295>: movl %eax, %edi 0x7fff8e2c25a9 <+297>: callq 0x7fff8e482080 ; symbol stub for: kill 0x7fff8e2c25ae <+302>: leaq 0x36325e(%rip), %rax ; "*** __CFTypeCollectionRetain() called with NULL; likely a collection has been corrupted ***" 0x7fff8e2c25b5 <+309>: movq %rax, -0x17f460c4(%rip) ; gCRAnnotations + 8 0x7fff8e2c25bc <+316>: int3 -> 0x7fff8e2c25bd <+317>: jmp 0x7fff8e2c259d ; <+285> 0x7fff8e2c25bf <+319>: nop 时,它还必须给出struct sockaddr的长度。例如,请参阅struct sockaddr

sendto()

使用缓冲区的大小,你应该能够很好地猜测你需要使用什么类型的ssize_t sendto (int sockfd, const void *buf, size_t buflen, int flags, const struct sockaddr *addr, socklen_t addrlen);

sockaddr

在理想情况下,if (addr.sa_family == AF_UNSPEC) { switch (addrlen) { case sizeof (struct sockaddr_in): { addr.sa_family = AF_INET; break; } case sizeof (struct sockaddr_in6): { addr.sa_family = AF_INET6; break; } default: { // handle error break; } } } 已经设置为sa_family(IPv4)或AF_INET(IPv6),但不幸的是,这似乎并非如此