Skip to content
Browse files

Added network suppport thanks to Matt_P and phiren! A network example…

… application has also been included.
  • Loading branch information...
1 parent 2a7e861 commit d54638ba29525ee03b332ac0c890b28fc853a3d7 @AerialX committed
View
19 psl1ght/include/arpa/inet.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <netinet/in.h>
+#include <stdint.h>
+
+#define htonl(hostlong) (hostlong)
+#define htons(hostshort) (hostshort)
+#define ntohl(netlong) (netlong)
+#define ntohs(netshort) (netshort)
+
+in_addr_t inet_addr(const char* cp);
+in_addr_t inet_lnaof(struct in_addr in);
+struct in_addr inet_makeaddr(in_addr_t net, in_addr_t lna);
+in_addr_t inet_netof(struct in_addr in);
+in_addr_t inet_network(const char* cp);
+char* inet_ntoa(struct in_addr in);
+int inet_aton(const char* cp, struct in_addr* inp);
+const char* inet_ntop(int af, const void* src, char* dst, socklen_t size);
+int inet_pton(int af, const char* src, void* dst);
View
35 psl1ght/include/netinet/in.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <psl1ght/types.h>
+
+#include <sys/socket.h>
+
+typedef u16 in_port_t;
+typedef u32 in_addr_t;
+
+struct in_addr
+{
+ in_addr_t s_addr;
+};
+
+struct sockaddr_in
+{
+ u8 sin_len;
+ sa_family_t sin_family;
+ in_port_t sin_port;
+ struct in_addr sin_addr;
+ unsigned char sin_zero[0x08];
+};
+
+#define IPPROTO_IP 0x00
+#define IPPROTO_ICMP 0x01
+#define IPPROTO_TCP 0x06
+#define IPPROTO_UDP 0x11
+#define IPPROTO_ICMPV6 0x3A
+
+#define INADDR_ANY 0x00000000
+#define INADDR_LOOPBACK 0x7F000001
+#define INADDR_BROADCAST 0xFFFFFFFF
+#define INADDR_NONE 0xFFFFFFFF
+
+#include <arpa/inet.h>
View
37 psl1ght/include/psl1ght/lv2/net.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <psl1ght/lv2.h>
+
+#include <sys/socket.h>
+
+typedef u32 lv2_socklen_t;
+
+struct lv2_iovec
+{
+ u32 padding1;
+ lv2_void iov_base;
+ u32 padding2;
+ lv2_size_t iov_len;
+};
+
+struct lv2_msghdr
+{
+ u32 padding1;
+ lv2_void msg_name;
+ lv2_socklen_t msg_namelen;
+ u32 padding2;
+ u32 padding3;
+ lv2_void msg_iov;
+ s32 msg_iovlen;
+ u32 padding4;
+ u32 padding5;
+ lv2_void msg_control;
+ lv2_socklen_t msg_controllen;
+ s32 msg_flags;
+};
+
+LV2_SYSCALL lv2NetConnect(int socket, const struct sockaddr* address, lv2_socklen_t address_len) { return Lv2Syscall3(702, socket, (u64)address, address_len); }
+LV2_SYSCALL lv2NetSendto(int socket, const void* message, size_t length, int flags, const struct sockaddr* dest_addr, socklen_t dest_len) { return Lv2Syscall6(710, socket, (u64)message, length, flags, (u64)dest_addr, dest_len); }
+LV2_SYSCALL lv2NetShutdown(int socket, int how) { return Lv2Syscall2(712, socket, how); }
+LV2_SYSCALL lv2NetSocket(int domain, int type, int protocol) { return Lv2Syscall3(713, domain, type, protocol); }
+LV2_SYSCALL lv2NetClose(int socket) { return Lv2Syscall1(714, socket); }
View
113 psl1ght/include/sys/socket.h
@@ -0,0 +1,113 @@
+#pragma once
+
+#include <psl1ght/types.h>
+#include <sys/types.h>
+
+typedef u64 socklen_t;
+typedef u8 sa_family_t;
+
+struct sockaddr
+{
+ u8 sa_len;
+ sa_family_t sa_family;
+ char sa_data[];
+};
+
+struct iovec
+{
+ void* iov_base;
+ size_t iov_len;
+};
+
+struct msghdr
+{
+ void* msg_name;
+ socklen_t msg_namelen;
+ struct iovec* msg_iov;
+ int msg_iovlen;
+ void* msg_control;
+ socklen_t msg_controllen;
+ int msg_flags;
+};
+
+struct cmsghdr
+{
+ socklen_t cmsg_len;
+ int cmsg_level;
+ int cmsg_type;
+};
+
+struct linger
+{
+ int l_onoff;
+ int l_linger;
+};
+
+#define SOCK_STREAM 0x0001
+#define SOCK_DGRAM 0x0002
+#define SOCK_RAW 0x0003
+
+#define SOL_SOCKET 0xFFFF
+
+#define SO_REUSEADDR 0x0004
+#define SO_KEEPALIVE 0x0008
+#define SO_BROADCAST 0x0020
+#define SO_LINGER 0x0080
+#define SO_OOBINLINE 0x0100
+#define SO_REUSEPORT 0x0200
+#define SO_SNDBUF 0x1001
+#define SO_RCVBUF 0x1002
+#define SO_SNDLOWAT 0x1003
+#define SO_RCVLOWAT 0x1004
+#define SO_SNDTIMEO 0x1005
+#define SO_RCVTIMEO 0x1006
+#define SO_ERROR 0x1007
+#define SO_TYPE 0x1008
+#define SO_NBIO 0x1100
+
+#define MSG_OOB 0x0001
+#define MSG_PEEK 0x0002
+#define MSG_DONTROUTE 0x0004
+#define MSG_EOR 0x0008
+#define MSG_TRUNC 0x0010
+#define MSG_CTRUNC 0x0020
+#define MSG_WAITALL 0x0040
+#define MSG_DONTWAIT 0x0080
+#define MSG_BCAST 0x0100
+#define MSG_MCAST 0x0200
+
+#define AF_UNSPEC 0x0000
+#define AF_UNIX 0x0001
+#define AF_INET 0x0002
+#define AF_INET6 0x0018
+#define AF_MAX 0x0020
+
+#define SHUT_RD 0x0000
+#define SHUT_WR 0x0001
+#define SHUT_RDWR 0x0002
+
+#define PF_INET AF_INET
+#define PF_INET6 AF_INET6
+
+int accept(int socket, struct sockaddr* address, socklen_t* address_len);
+int bind(int socket, const struct sockaddr* address, socklen_t address_len);
+int connect(int socket, const struct sockaddr* address, socklen_t address_len);
+int getpeername(int socket, struct sockaddr* address, socklen_t* address_len);
+int getsockname(int socket, struct sockaddr* address, socklen_t* address_len);
+int getsockopt(int socket, int level, int option_name, void* option_value,
+ socklen_t* option_len);
+int listen(int socket, int backlog);
+ssize_t recv(int socket, void* buffer, size_t length, int flags);
+ssize_t recvfrom(int socket, void* buffer, size_t length, int flags,
+ struct sockaddr* address, socklen_t* address_len);
+ssize_t recvmsg(int socket, struct msghdr* message, int flags);
+ssize_t send(int socket, const void* message, size_t length, int flags);
+ssize_t sendmsg(int socket, const struct msghdr* message, int flags);
+ssize_t sendto(int socket, const void* message, size_t length, int flags,
+ const struct sockaddr* dest_addr, socklen_t dest_len);
+int setsockopt(int socket, int level, int option_name, const void* option_value,
+ socklen_t option_len);
+int shutdown(int socket, int how);
+int socket(int domain, int type, int protocol);
+int socketpair(int domain, int type, int protocol, int socket_vector[2]);
+
View
69 psl1ght/libc-glue-ppu/source/socket.c
@@ -0,0 +1,69 @@
+#include <psl1ght/lv2/net.h>
+
+#include <psl1ght/lv2/errno.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <stdio.h>
+
+int connect(int socket, const struct sockaddr* address, socklen_t address_len)
+{
+ return lv2Errno(lv2NetConnect(socket, address, (lv2_socklen_t)address_len));
+}
+
+int socket(int domain, int type, int protocol)
+{
+ s32 ret = lv2NetSocket(domain, type, protocol);
+ if (ret < 0)
+ return lv2Errno(ret);
+ return ret;
+}
+
+ssize_t send(int socket, const void* message, size_t length, int flags)
+{
+ return sendto(socket, message, length, flags, NULL, 0);
+}
+
+ssize_t sendto(int socket, const void* message, size_t length, int flags,
+ const struct sockaddr* dest_addr, socklen_t dest_len)
+{
+ s32 ret = lv2NetSendto(socket, message, length, flags, dest_addr, dest_len);
+ if (ret < 0)
+ return lv2Errno(ret);
+ return ret;
+}
+
+int shutdown(int socket, int how)
+{
+ return lv2Errno(lv2NetShutdown(socket, how));
+}
+
+int inet_aton(const char* cp, struct in_addr* inp)
+{
+ u32 num1;
+ u32 num2;
+ u32 num3;
+ u32 num4;
+ if (sscanf(cp, "%u.%u.%u.%u", &num1, &num2, &num3, &num4) != 4)
+ return 0;
+ if ((num1 | num2 | num3 | num4) & 0xFFFFFF00)
+ return 0;
+
+ inp->s_addr = htonl((num1 << 24) | (num2 << 16) | (num3 << 8) | num4);
+
+ return 1;
+}
+
+int inet_pton(int af, const char* src, void* dst)
+{
+ switch (af) {
+ case AF_INET:
+ return inet_aton(src, (struct in_addr*)dst);
+ case AF_INET6:
+ break;
+ }
+
+ return 1;
+}
View
60 samples/network/Makefile
@@ -0,0 +1,60 @@
+.SUFFIXES:
+ifeq ($(strip $(PSL1GHT)),)
+$(error "PSL1GHT must be set in the environment.")
+endif
+
+include $(PSL1GHT)/Makefile.base
+
+TARGET := $(notdir $(CURDIR))
+BUILD := build
+SOURCE := source
+INCLUDE := include
+DATA := data
+LIBS :=
+
+CFLAGS += -g -O2 -Wall --std=gnu99
+CXXFLAGS += -g -O2 -Wall
+
+ifneq ($(BUILD),$(notdir $(CURDIR)))
+
+export OUTPUT := $(CURDIR)/$(TARGET)
+export VPATH := $(foreach dir,$(SOURCE),$(CURDIR)/$(dir)) \
+ $(foreach dir,$(DATA),$(CURDIR)/$(dir))
+export BUILDDIR := $(CURDIR)/$(BUILD)
+export DEPSDIR := $(BUILDDIR)
+
+CFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.c)))
+CXXFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.cpp)))
+SFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.S)))
+BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.bin)))
+
+export OFILES := $(CFILES:.c=.o) \
+ $(CXXFILES:.cpp=.o) \
+ $(SFILES:.S=.o)
+
+export BINFILES := $(BINFILES:.bin=.bin.h)
+
+export INCLUDES := $(foreach dir,$(INCLUDE),-I$(CURDIR)/$(dir)) \
+ -I$(CURDIR)/$(BUILD)
+
+.PHONY: $(BUILD) clean
+
+$(BUILD):
+ @[ -d $@ ] || mkdir -p $@
+ @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+
+clean:
+ @echo Clean...
+ @rm -rf $(BUILD) $(OUTPUT).elf $(OUTPUT).self $(OUTPUT).a
+
+else
+
+DEPENDS := $(OFILES:.o=.d)
+
+$(OUTPUT).self: $(OUTPUT).elf
+$(OUTPUT).elf: $(OFILES)
+$(OFILES): $(BINFILES)
+
+-include $(DEPENDS)
+
+endif
View
105 samples/network/source/main.c
@@ -0,0 +1,105 @@
+// This sample application will connect to a specified IP using the PS3's
+// network and send a small message. It will try sending it with both
+// TCP and UDP.
+
+#include <psl1ght/lv2/net.h>
+
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+// Configure these (especially the IP) to your own setup.
+// Use netcat to receive the results on your PC:
+// TCP: nc -l -p 4000
+// UDP: nc -u -l -p 4000
+// For some versions of netcat the -p option may need to be removed.
+#define TESTSTRING "y halo thar\n"
+#define TESTIP "192.168.1.13"
+#define TESTPORT 4000
+
+void tcp_test()
+{
+ printf("Beginning TCP socket test...\n");
+
+ int s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (s < 0) {
+ printf("Unable to create a socket: %d\n", errno);
+ return;
+ }
+ printf("Socket created: %d\n", s);
+
+ struct sockaddr_in server;
+ memset(&server, 0, sizeof(server));
+ server.sin_len = sizeof(server);
+ server.sin_family = AF_INET;
+ inet_pton(AF_INET, TESTIP, &server.sin_addr);
+ server.sin_port = htons(TESTPORT);
+
+ int ret = connect(s, (struct sockaddr*)&server, sizeof(server));
+ if (ret) {
+ printf("Unable to connect to server: %d\n", errno);
+ return;
+ }
+ printf("Connected to server successfully!\n");
+ ret = send(s, TESTSTRING, strlen(TESTSTRING), 0);
+ if (ret < 0)
+ printf("Unable to send to server: %d\n", errno);
+ else
+ printf("Sent %d bytes to server!\n", ret);
+
+ ret = shutdown(s, SHUT_RDWR);
+ if (ret < 0)
+ printf("Unable to shutdown socket: %d\n", errno);
+ else
+ printf("Socket shutdown successfully!\n");
+
+ ret = lv2NetClose(s); // TODO: close() doesn't differentiate sockets from files yet.
+ if (ret < 0)
+ printf("Unable to close socket: %d\n", ret);
+ else
+ printf("TCP test successful!\n");
+}
+
+void udp_test()
+{
+ printf("Beginning UDP socket test...\n");
+
+ int s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0) {
+ printf("Unable to create a socket: %d\n", errno);
+ return;
+ }
+ printf("Socket created: %d\n", s);
+
+ struct sockaddr_in server;
+ memset(&server, 0, sizeof(server));
+ server.sin_len = sizeof(server);
+ server.sin_family = AF_INET;
+ inet_pton(AF_INET, TESTIP, &server.sin_addr);
+ server.sin_port = htons(TESTPORT);
+
+ int ret = sendto(s, TESTSTRING, strlen(TESTSTRING), 0, (struct sockaddr*)&server, sizeof(server));
+ if (ret < 0)
+ printf("Unable to send to server: %d\n", errno);
+ else
+ printf("Sent %d bytes to server!\n", ret);
+
+ ret = lv2NetClose(s); // TODO: close() doesn't differentiate sockets from files yet.
+ if (ret < 0)
+ printf("Unable to close socket: %d\n", ret);
+ else
+ printf("UDP test successful!\n");
+
+}
+
+int main(int argc, const char* argv[])
+{
+ tcp_test();
+ udp_test();
+ return 0;
+}

0 comments on commit d54638b

Please sign in to comment.
Something went wrong with that request. Please try again.