* Implemented a new test program for AF_LINK level sockets based on udp_echo.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39720 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2010-12-04 14:27:34 +00:00
parent a25f37e7b2
commit 7c10ef0cf9
2 changed files with 188 additions and 0 deletions

View File

@ -15,6 +15,8 @@ SimpleTest tcp_client : tcp_client.c : $(TARGET_NETWORK_LIBS) ;
SimpleTest ipv46_server : ipv46_server.cpp : $(TARGET_NETWORK_LIBS) ;
SimpleTest ipv46_client : ipv46_client.cpp : $(TARGET_NETWORK_LIBS) ;
SimpleTest link_echo : link_echo.cpp : $(TARGET_NETWORK_LIBS) bnetapi be ;
SimpleTest getpeername : getpeername.cpp : $(TARGET_NETWORK_LIBS) ;
SimpleTest tcp_connection_test : tcp_connection_test.cpp

View File

@ -0,0 +1,186 @@
/*
* Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Oliver Tappe, zooey@hirschkaefer.de
* Axel Dörfler, axeld@pinc-software.de
*/
#include <ctype.h>
#include <errno.h>
#include <net/if_dl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <NetworkInterface.h>
extern const char* __progname;
static const size_t kBufferSize = 1500;
static const uint32 kFrameType = 0x8888;
static const char* kProgramName = __progname;
static void
parse_mac_address(const char* string, uint8* mac)
{
if (sscanf(string, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &mac[0],
&mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) < 6) {
fprintf(stderr, "%s: Invalid MAC address.\n", kProgramName);
exit(EXIT_FAILURE);
}
}
static void
link_client(int fd, const BNetworkAddress& server)
{
char buffer[kBufferSize];
while (fgets(buffer, kBufferSize, stdin) != NULL) {
size_t length = strlen(buffer);
if (length > 0)
length--;
if (sendto(fd, buffer, length, 0, server, server.Length()) < 0) {
fprintf(stderr, "%s: sendto(): %s\n", kProgramName,
strerror(errno));
exit(EXIT_FAILURE);
}
printf("sent %" B_PRIuSIZE " bytes...\n", length);
ssize_t bytesRead = recvfrom(fd, buffer, kBufferSize - 1, 0, NULL,
NULL);
if (bytesRead < 0) {
fprintf(stderr, "%s: recvfrom(): %s\n", kProgramName,
strerror(errno));
exit(EXIT_FAILURE);
}
buffer[bytesRead] = 0;
printf("-> %s\n", buffer);
}
}
static void
link_server(int fd)
{
while (true) {
BNetworkAddress client;
socklen_t length = sizeof(client);
char buffer[kBufferSize];
ssize_t bytesRead = recvfrom(fd, buffer, kBufferSize - 1, 0, client,
&length);
if (bytesRead < 0) {
fprintf(stderr, "%s: recvfrom(): %s\n", kProgramName,
strerror(errno));
exit(EXIT_FAILURE);
}
buffer[bytesRead] = '\0';
printf("got <%s> from client %s\n", buffer, client.ToString().String());
for (int i = 0; i < bytesRead; i++) {
if (islower(buffer[i]))
buffer[i] = toupper(buffer[i]);
else if (isupper(buffer[i]))
buffer[i] = tolower(buffer[i]);
}
printf("replying <%s>\n", buffer);
if (sendto(fd, buffer, bytesRead, 0, client, client.Length()) < 0) {
fprintf(stderr, "%s: sendto(): %s\n", kProgramName,
strerror(errno));
exit(EXIT_FAILURE);
}
}
}
int
main(int argc, char** argv)
{
enum {
CLIENT_MODE,
SERVER_MODE,
BROADCAST_MODE,
} mode = CLIENT_MODE;
if (argc < 3) {
fprintf(stderr, "usage: %s <device> client <server-mac-address>\n"
"or %s <device> broadcast\n"
"or %s <device> server\n", kProgramName, kProgramName,
kProgramName);
exit(EXIT_FAILURE);
}
BNetworkInterface interface(argv[1]);
BNetworkAddress link;
if (interface.GetHardwareAddress(link) != B_OK)
perror("get hardware address");
BNetworkAddress server;
if (!strcmp(argv[2], "client")) {
mode = CLIENT_MODE;
if (argc < 4) {
fprintf(stderr, "usage: %s client <server-mac-address>\n",
kProgramName);
exit(EXIT_FAILURE);
}
uint8 macAddress[6];
parse_mac_address(argv[3], macAddress);
server.SetToLinkLevel(macAddress, sizeof(macAddress));
} else if (!strcmp(argv[2], "broadcast")) {
mode = BROADCAST_MODE;
uint8 broadcastAddress[6];
for (size_t i = 0; i < sizeof(broadcastAddress); i++)
broadcastAddress[i] = 0xff;
server.SetToLinkLevel(broadcastAddress, sizeof(broadcastAddress));
} else if (!strcmp(argv[2], "server"))
mode = SERVER_MODE;
int fd = socket(AF_LINK, SOCK_DGRAM, 0);
if (fd < 0)
perror("socket");
// bind to protocol
link.SetLinkLevelFrameType(kFrameType);
server.SetLinkLevelFrameType(kFrameType);
if (bind(fd, link, link.Length()) != 0)
perror("bind");
socklen_t length = sizeof(link);
if (getsockname(fd, link, &length) != 0)
perror("getsockname");
printf("bound to %s\n", link.ToString().String());
if (mode == BROADCAST_MODE) {
int option = 1;
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
}
switch (mode) {
case CLIENT_MODE:
case BROADCAST_MODE:
link_client(fd, server);
break;
case SERVER_MODE:
link_server(fd);
break;
}
return 0;
}