diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-12 15:51:42 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-12 15:51:42 +0100 |
commit | a017a7744279a29ab490c0aa7d2a81deb0997ae4 (patch) | |
tree | b33d8d4c51d437b460ffa2ce9213edf40644bccd /Userland | |
parent | 8e667747f0ac744e74b1acb5b83a0b9db0b7acde (diff) | |
download | serenity-a017a7744279a29ab490c0aa7d2a81deb0997ae4.zip |
Kernel+LibC+Userland: Start working on an IPv4 socket backend.
The first userland networking program will be "ping" :^)
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/.gitignore | 1 | ||||
-rw-r--r-- | Userland/Makefile | 5 | ||||
-rw-r--r-- | Userland/ping.cpp | 58 |
3 files changed, 64 insertions, 0 deletions
diff --git a/Userland/.gitignore b/Userland/.gitignore index fc991ef960..17a5d60640 100644 --- a/Userland/.gitignore +++ b/Userland/.gitignore @@ -37,3 +37,4 @@ su env chown stat +ping diff --git a/Userland/Makefile b/Userland/Makefile index 3450d3d912..6acf59947b 100644 --- a/Userland/Makefile +++ b/Userland/Makefile @@ -33,6 +33,7 @@ OBJS = \ su.o \ env.o \ stat.o \ + ping.o \ rm.o APPS = \ @@ -71,6 +72,7 @@ APPS = \ su \ env \ stat \ + ping \ rm ARCH_FLAGS = @@ -198,6 +200,9 @@ env: env.o stat: stat.o $(LD) -o $@ $(LDFLAGS) $< -lc +ping: ping.o + $(LD) -o $@ $(LDFLAGS) $< -lc + .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Userland/ping.cpp b/Userland/ping.cpp new file mode 100644 index 0000000000..321cdff48c --- /dev/null +++ b/Userland/ping.cpp @@ -0,0 +1,58 @@ +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/ip_icmp.h> +#include <stdio.h> +#include <string.h> +#include <Kernel/NetworkOrdered.h> + +NetworkOrdered<word> internet_checksum(const void* ptr, size_t count) +{ + dword checksum = 0; + auto* w = (const word*)ptr; + while (count > 1) { + checksum += convert_between_host_and_network(*w++); + if (checksum & 0x80000000) + checksum = (checksum & 0xffff) | (checksum >> 16); + count -= 2; + } + while (checksum >> 16) + checksum = (checksum & 0xffff) + (checksum >> 16); + return ~checksum & 0xffff; +} + + +int main(int argc, char** argv) +{ + int fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if (fd < 0) { + perror("socket"); + return 1; + } + + sockaddr_in peer_address; + memset(&peer_address, 0, sizeof(peer_address)); + peer_address.sin_family = AF_INET; + peer_address.sin_port = 0; + peer_address.sin_addr.s_addr = 0x0105a8c0; // 192.168.5.1 + + struct PingPacket { + struct icmphdr header; + char msg[64 - sizeof(struct icmphdr)]; + }; + + PingPacket ping_packet; + memset(&ping_packet, 0, sizeof(PingPacket)); + + ping_packet.header.type = 8; // Echo request + strcpy(ping_packet.msg, "Hello there!\n"); + + ping_packet.header.checksum = htons(internet_checksum(&ping_packet, sizeof(PingPacket))); + + int rc = sendto(fd, &ping_packet, sizeof(PingPacket), 0, (const struct sockaddr*)&peer_address, sizeof(sockaddr_in)); + if (rc < 0) { + perror("sendto"); + return 1; + } + + return 0; +} |