Created
January 5, 2016 23:11
-
-
Save tjs-w/57b99c2a7a50fff5dc3f to your computer and use it in GitHub Desktop.
TCP_MD5SIG socketopt in Linux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* tcpmd5_server6.c: TCP_MD5SIG | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <netinet/tcp.h> | |
#include <netdb.h> | |
#include <arpa/inet.h> | |
#define BUFFERSZ 256 | |
struct tcp_md5sig md5; | |
static inline void error(char *msg) { | |
perror(msg); | |
exit(1); | |
} | |
int main(int argc, char *argv[]) { | |
int sockfd, newsockfd, portno; | |
socklen_t clilen; | |
char buffer[BUFFERSZ], *key, *s6ip, *sport, *c6ip, *cport; | |
struct sockaddr_in6 serv_addr, saddr, cli_addr; | |
int n, r; | |
char client_addr_ipv6[100]; | |
if (argc != 6) { | |
fprintf(stderr, "Usage: %s <server IPv6> <server port> " | |
"<client IPv6> <client port> <MD5 key>\n", | |
argv[0]); | |
return -1; | |
} | |
s6ip = argv[1]; | |
sport = argv[2]; | |
c6ip = argv[3]; | |
cport = argv[4]; | |
key = argv[5]; | |
printf("\nIPv6 TCP Server (TCP_MD5SIG) ...\n"); | |
//Sockets Layer Call: socket() | |
sockfd = socket(AF_INET6, SOCK_STREAM, 0); | |
if (sockfd < 0) | |
error("ERROR opening socket"); | |
bzero((char *) &serv_addr, sizeof(serv_addr)); | |
portno = atoi(sport); | |
serv_addr.sin6_family = AF_INET6; | |
if(inet_pton(AF_INET6, s6ip, &serv_addr.sin6_addr) <= 0) | |
error("ERROR on inet_pton"); | |
serv_addr.sin6_port = htons(portno); | |
//Sockets Layer Call: bind() | |
if (bind(sockfd, (struct sockaddr *) &serv_addr, | |
sizeof(serv_addr)) < 0) | |
error("ERROR on binding"); | |
// Client sockaddr_in6 for TCPMD5_SIG | |
memset(&saddr, '0', sizeof(saddr)); | |
saddr.sin6_family = AF_INET6; | |
if(inet_pton(AF_INET6, c6ip, &saddr.sin6_addr)<=0) | |
error("ERROR on inet_pton"); | |
saddr.sin6_port = htons(atoi(cport)); | |
//memcpy(&md5.tcpm_addr, &saddr, sizeof(saddr)); | |
md5.tcpm_addr = *(struct sockaddr_storage *) &saddr; | |
strcpy(md5.tcpm_key, key); | |
md5.tcpm_keylen = strlen(key); | |
if ((r = setsockopt(sockfd, IPPROTO_TCP, TCP_MD5SIG, | |
&md5, sizeof(md5))) < 0) | |
error("listen setsockopt TCP_MD5SIG"); | |
//Sockets Layer Call: listen() | |
listen(sockfd, 5); | |
clilen = sizeof(cli_addr); | |
//Sockets Layer Call: accept() | |
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); | |
if (newsockfd < 0) | |
error("ERROR on accept"); | |
//Sockets Layer Call: inet_ntop() | |
inet_ntop(AF_INET6, &(cli_addr.sin6_addr),client_addr_ipv6, 100); | |
printf("Incoming connection from client having IPv6 address: %s\n", | |
client_addr_ipv6); | |
memset(buffer,0, BUFFERSZ); | |
//Sockets Layer Call: recv() | |
n = recv(newsockfd, buffer, BUFFERSZ-1, 0); | |
if (n < 0) | |
error("ERROR reading from socket"); | |
printf("Message from client: %s\n", buffer); | |
//Sockets Layer Call: send() | |
n = send(newsockfd, "Server got your message", | |
strlen("Server got your message"), 0); | |
if (n < 0) | |
error("ERROR writing to socket"); | |
//Sockets Layer Call: close() | |
close(sockfd); | |
close(newsockfd); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* tcpmd5_client6.c: TCP_MD5SIG | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <netinet/tcp.h> | |
#include <netdb.h> | |
#define BUFFERSZ 256 | |
static inline void error(char *msg) { | |
perror(msg); | |
exit(0); | |
} | |
struct tcp_md5sig md5; | |
int main(int argc, char *argv[]) { | |
int sockfd, portno, n, r; | |
struct sockaddr_in6 cl_addr, serv_addr; | |
struct hostent *server; | |
char buffer[BUFFERSZ] = "This is a string from client!"; | |
char *key, *s6ip, *sport, *c6ip, *cport; | |
if (argc != 6) { | |
fprintf(stderr, "Usage: %s <server IPv6> <server port> " | |
"<client IPv6> <client port> <MD5 key>\n", | |
argv[0]); | |
return -1; | |
} | |
s6ip = argv[1]; | |
sport = argv[2]; | |
c6ip = argv[3]; | |
cport = argv[4]; | |
key = argv[5]; | |
printf("\nIPv6 TCP Client Started...\n"); | |
//Sockets Layer Call: socket() | |
sockfd = socket(AF_INET6, SOCK_STREAM, 0); | |
if (sockfd < 0) | |
error("ERROR opening socket"); | |
//Sockets Layer Call: bind() | |
memset((char *) &cl_addr, 0, sizeof(cl_addr)); | |
cl_addr.sin6_family = AF_INET6; | |
if(inet_pton(AF_INET6, c6ip, &cl_addr.sin6_addr)<=0) | |
error("ERROR on inet_pton"); | |
cl_addr.sin6_port = htons(atoi(cport)); | |
if (bind(sockfd, (struct sockaddr *) &cl_addr, | |
sizeof(cl_addr)) < 0) | |
error("ERROR on binding"); | |
memset((char *) &serv_addr, 0, sizeof(serv_addr)); | |
serv_addr.sin6_family = AF_INET6; | |
if(inet_pton(AF_INET6, s6ip, | |
&serv_addr.sin6_addr)<=0) | |
error("ERROR on inet_pton"); | |
serv_addr.sin6_port = htons(atoi(sport)); | |
memcpy(&md5.tcpm_addr, &serv_addr, sizeof(serv_addr)); | |
strcpy(md5.tcpm_key, key); | |
md5.tcpm_keylen = strlen(key); | |
if ((r = setsockopt(sockfd, IPPROTO_TCP, TCP_MD5SIG, | |
&md5, sizeof(md5))) < 0) | |
error("listen setsockopt TCP_MD5SIG"); | |
//Sockets Layer Call: connect() | |
if (connect(sockfd, (struct sockaddr *) &serv_addr, | |
sizeof(serv_addr)) < 0) | |
error("ERROR connecting"); | |
//Sockets Layer Call: send() | |
n = send(sockfd, buffer, strlen(buffer)+1, 0); | |
if (n < 0) | |
error("ERROR writing to socket"); | |
memset(buffer, 0, BUFFERSZ); | |
//Sockets Layer Call: recv() | |
n = recv(sockfd, buffer, BUFFERSZ-1, 0); | |
if (n < 0) | |
error("ERROR reading from socket"); | |
printf("Message from server: %s\n", buffer); | |
//Sockets Layer Call: close() | |
close(sockfd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment