sock_connect error 47 from KEXT but not from user space includes two sample programs demonstrating the issue

Error 47 is EAFNOSUPPORT */ Address family not supported by protocol family */ in sys/errno.h

I have created a test userland program as well as a test KEXT. Both can be tested against a netcat listener i.e. ncat -l 8080

Here is the userland program that functions properly. Followed by the KEXT that emits error 47 on sock_connect().

*/

test against ncat -l 8080

Modify the IP Address in the inet_aton call below.

gcc -o test test.c

*/

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <string.h>

#include <errno.h>

#include <arpa/inet.h>

#include <unistd.h>

int main(void)

{

struct sockaddr_in srvaddr;

memset(&srvaddr, 0, sizeof(srvaddr));

int sockfd = 0;

int error = 0;

ssize_t sent = 0;

char hello[] = "hello\n";

sockfd = socket(PF_INET, SOCK_STREAM, 0);

if(sockfd == -1) {

printf("Error creating socket\n");

return -1;

} else {

printf("socket created\n");

srvaddr.sin_family = AF_INET;

srvaddr.sin_port = htons(8080);

error = inet_aton("10.0.0.1", &srvaddr.sin_addr);

if(error == 0) {

printf("invalid!\n");

close(sockfd);

return -1;

}

error = connect(sockfd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));

if(error == -1) {

printf("connect error %s\n", strerror(errno));

close(sockfd);

} else {

printf("Connected\n");

sent = send(sockfd, hello, strlen(hello), 0);

printf("sent %ld\n", sent);

}

close(sockfd);

}

return 1;

}


This program successfully connects and sends the message to the netcat listener.


Here is the KEXT that emits error 47 on sock_connect. Because of the error, I did not bother to include the send function.

/*


Follow the guide here: https://developer.apple.com/library/prerelease/mac/documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptKEXT/kext_tutorial.html#//apple_ref/doc/uid/20002365-BABJHCJA

and then paste in the bellow code.

*/

#include <mach/mach_types.h>

#include <libkern/libkern.h>

#include <sys/kpi_socket.h>

#include <netinet/in.h>

#include <sys/errno.h>

kern_return_t socket_start(kmod_info_t * ki, void *d);

kern_return_t socket_stop(kmod_info_t *ki, void *d);

kern_return_t socket_start(kmod_info_t * ki, void *d)

{

struct sockaddr_in srvaddr;

socket_t sock;

int error = 0;


error = sock_socket(PF_INET, SOCK_STREAM, 0, NULL, NULL, &sock);

if(error != 0) {

printf("sock_socket failed %d\n", error);

return KERN_FAILURE;

} else {

printf("sock_socket okay\n");

}


memset(&srvaddr, 0, sizeof(srvaddr));

srvaddr.sin_family = AF_INET;

srvaddr.sin_port = htons(8080);

error = inet_aton("10.0.0.1", &srvaddr.sin_addr);

if(error == 0) {

printf("invalid\n");

sock_close(sock);

return KERN_FAILURE;

}


error = sock_connect(sock, (struct sockaddr *)&srvaddr, MSG_DONTWAIT);

if (error == EINPROGRESS) {

printf("It worked EINPROGRESS\n");

} else if(error == 0) {

printf("connect okay\n");

} else {

printf("Error %d\n", error);

}

printf("closing socket\n");

sock_close(sock);

return KERN_SUCCESS;

}

kern_return_t socket_stop(kmod_info_t *ki, void *d)

{

return KERN_SUCCESS;

}



When this extension is loaded, the following output can be seen in /var/log/system.log


Feb 2 13:32:45 Hidden sudo[2403]: user : TTY=ttys000 ; PWD=/test/kext ; USER=root ; COMMAND=/sbin/kextload /tmp/socket.kext/

Feb 2 13:32:45 Hidden kernel[0]: sock_socket okay

Feb 2 13:32:45 Hidden kernel[0]: Error 47

Feb 2 13:32:45 Hidden kernel[0]: closing socket

Answered by DTS Engineer in 109925022

You don’t seem to be setting

sin_len
. That’s not necessary in user space because
connect()
has the
address_len
parameter, but the same is not true for
sock_connect()
in the kernel.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I even modified the above KEXT to be almost identical to the sample code in https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/NKEConceptual/SocketManipulation/SocketManipulation.html

and I still have the same problem.

I have also tried using sock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, &so); instead of sock_socket(PF_INET, SOCK_STREAM, 0, NULL, NULL, &so); PF_INET is defined as AF_INET in sys/socket.h so this had no effect.

protocol 0 is according to documentation supposed to use the default protocol for the family, but changing 0 to IPPROTO_TCP also did not change the outcome.

Accepted Answer

You don’t seem to be setting

sin_len
. That’s not necessary in user space because
connect()
has the
address_len
parameter, but the same is not true for
sock_connect()
in the kernel.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
sock_connect error 47 from KEXT but not from user space includes two sample programs demonstrating the issue
 
 
Q