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
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"