115 lines
3.1 KiB
C
115 lines
3.1 KiB
C
#include <arpa/inet.h>
|
|
#include <sys/socket.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <netdb.h>
|
|
#include <unistd.h>
|
|
|
|
#define SERVER "devloop.de"
|
|
#define PORT 25
|
|
|
|
#define RECEIVE_BUFFER 256
|
|
|
|
char* copyNtrim(char *str) {
|
|
char *ret = strdup(str);
|
|
|
|
for (int i = strlen(ret); i >= 0; i--) {
|
|
if (ret[i] == '\r' || ret[i] == '\n') {
|
|
ret[i] = '\0';
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void sendMessage(int sock, char *msg) {
|
|
int sendBytes = send(sock, msg, strlen(msg), 0);
|
|
if (sendBytes >= 0) {
|
|
printf("Send %d bytes to %s:%d: %s\n", sendBytes, SERVER, PORT, copyNtrim(msg));
|
|
} else {
|
|
fprintf(stderr, "Failed to send message to %s:%d (%d): %s", SERVER, PORT, errno, strerror(errno));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
void receiveMessage(int sock, char *buf, int bufLen) {
|
|
int recvBytes = recv(sock, buf, bufLen, 0);
|
|
if (recvBytes >= 0) {
|
|
printf("Received %d bytes from %s: %s\n", recvBytes, SERVER, copyNtrim(buf));
|
|
} else {
|
|
fprintf(stderr, "Error receiving data from %s (%d): %s", SERVER, errno, strerror(errno));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
struct sockaddr_in6* lookup(char *host) {
|
|
int err;
|
|
|
|
// lookup IPv6 address
|
|
struct addrinfo hints;
|
|
struct addrinfo *serverAddrs;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET6;
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
err = getaddrinfo(host, NULL, &hints, &serverAddrs);
|
|
if (err) {
|
|
fprintf(stderr, "Error looking up host %s (%d): %s\n", host, err, gai_strerror(err));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// print out IPv6 addresses
|
|
struct addrinfo *serverAddr;
|
|
struct sockaddr_in6 *serverAddr_in6;
|
|
for (serverAddr = serverAddrs; serverAddr != NULL; serverAddr = serverAddr->ai_next) {
|
|
serverAddr_in6 = (struct sockaddr_in6 *)serverAddr->ai_addr;
|
|
unsigned char buf[sizeof(struct in6_addr)];
|
|
char serverAddr_str[INET6_ADDRSTRLEN];
|
|
printf("IPv6 of %s: %s\n", host, inet_ntop(AF_INET6, &serverAddr_in6->sin6_addr, serverAddr_str, INET6_ADDRSTRLEN));
|
|
}
|
|
|
|
return serverAddr_in6;
|
|
}
|
|
|
|
int connectTo(char *host, int port) {
|
|
int err;
|
|
|
|
// socket
|
|
int sock = socket(AF_INET6, SOCK_STREAM, 0);
|
|
if (sock == -1) {
|
|
fprintf(stderr, "Error creating socket (%d): %s\n", errno, strerror(errno));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
struct sockaddr_in6 *serverAddr_in6 = lookup(host);
|
|
|
|
// connect last IPv6 address
|
|
serverAddr_in6->sin6_port = htons(port);
|
|
err = connect(sock, (struct sockaddr *)serverAddr_in6, sizeof(*serverAddr_in6));
|
|
if (err) {
|
|
fprintf(stderr, "Error connecting %s:%d (%d): %s\n", host, port, err, gai_strerror(err));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
return sock;
|
|
}
|
|
|
|
int main() {
|
|
char buf[RECEIVE_BUFFER];
|
|
|
|
// connect
|
|
int sock = connectTo(SERVER, PORT);
|
|
|
|
// chat
|
|
receiveMessage(sock, buf, RECEIVE_BUFFER);
|
|
sendMessage(sock, "HELO tuxic.dyndns.devloop.de\r\n");
|
|
receiveMessage(sock, buf, RECEIVE_BUFFER);
|
|
sendMessage(sock, "QUIT\r\n");
|
|
receiveMessage(sock, buf, RECEIVE_BUFFER);
|
|
|
|
// end session
|
|
close(sock);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
} |