在内核模块中,如果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;
};
答案 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),但不幸的是,这似乎并非如此