Error connecting server and client programs - tcpclient

I wrote those two codes. server and client.
//***Server***
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>
#define BUF_SIZE 1024
#define OPSZ 4
void ErrorHandling(char *message);
int calculate(int opnum, int opnds[], char op);
int main(int argc, char *argv)
{
WSADATA wsaData;
SOCKET hServSock, hClntSock;
char opinfo[BUF_SIZE];
int result, opndCnt, i;
int recvCnt, recvLen;
SOCKADDR_IN servAdr, clntAdr;
int clntAdrSize;
if(argc != 2)
{
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
ErrorHandling("WSAStartup() error!");
hServSock = socket(PF_INET, SOCK_STREAM, 0);
if(hServSock == INVALID_SOCKET)
ErrorHandling("socket() error");
memset(&servAdr, 0, sizeof(servAdr));
servAdr.sin_family = AF_INET;
servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
servAdr.sin_port = htons(atoi((char*)argv[1]));
if(bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
ErrorHandling("bind() error");
if(listen(hServSock, 5) == SOCKET_ERROR)
ErrorHandling("listen() error");
clntAdrSize = sizeof(clntAdr);
for(i=0; i<5; i++)
{
opndCnt = 0;
hClntSock = accept(hServSock, (SOCKADDR*)&clntAdr, &clntAdrSize);
recv(hClntSock, (char*)&opndCnt, 1, 0);
recvLen = 0;
while((opndCnt*OPSZ+1) > recvLen)
{
recvCnt = recv(hClntSock, &opinfo[recvLen], BUF_SIZE-1, 0);
recvLen += recvCnt;
}
result = calculate(opndCnt, (int*)opinfo, opinfo[recvLen-1]);
send(hClntSock, (char*)&result, sizeof(result), 0);
closesocket(hClntSock);
}
closesocket(hServSock);
WSACleanup();
return 0;
}
int calculate(int opnum, int opnds[], char op)
{
int result = opnds[0], i;
switch(op)
{
case '+':
for(i=1; i<opnum; i++) result += opnds[i];
break;
case '-':
for(i=1; i<opnum; i++) result -= opnds[i];
break;
case '*':
for(i=1; i<opnum; i++) result *= opnds[i];
break;
}
return result;
}
void ErrorHandling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
//***client***
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>
#define BUF_SIZE 1024
#define RLT_SIZE 4
#define OPSZ 4
void ErrorHandling(char *message);
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET hSocket;
char opmsg[BUF_SIZE];
int result, opndCnt, i;
SOCKADDR_IN servAdr;
if(argc != 3)
{
printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
ErrorHandling("WSAStartup() error!");
hSocket = socket(PF_INET, SOCK_STREAM, 0);
if(hSocket == INVALID_SOCKET)
ErrorHandling("socket() error");
memset(&servAdr, 0, sizeof(servAdr));
servAdr.sin_family = AF_INET;
servAdr.sin_addr.s_addr = inet_addr(argv[1]);
servAdr.sin_port = htons(atoi(argv[2]));
if(connect(hSocket, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
ErrorHandling("connect() error!");
else
puts("Connected..........");
fputs("Operand count: ", stdout);
scanf("%d", &opndCnt);
opmsg[0] = (char)opndCnt;
for(i=0; i<opndCnt; i++)
{
printf("Operand %d: ", i+1);
scanf("%d", (int*)&opmsg[i*OPSZ+1]);
}
fgetc(stdin);
fputs("Operator: ", stdout);
scanf("%c", &opmsg[opndCnt*OPSZ+1]);
send(hSocket, opmsg, opndCnt*OPSZ+2, 0);
recv(hSocket, (char*)&result, RLT_SIZE, 0);
printf("Operation result: %d \n", result);
closesocket(hSocket);
WSACleanup();
return 0;
}
void ErrorHandling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
I compiled those two codes (that means 2 projects separately) and that made Debug folder.
I saved those 2 project folders to Desktop.
I started cmd and then wrote
cd Desktop-> cd server -> cd Debug -> server 9190
but the error happens (I first coded server to turn the server on, and then I was planning to make the connection between the server and client.)

int main(int argc, char *argv) should read int main(int argc, char **argv)
char *argv[] would also work.
What does int argc, char *argv[] mean? might be worth a read.
Here is a link to a tutorial that will help you get started with winsock programming.

Related

Using execvp with low level IO and standard input

I am trying to use low level IO (Read) to read in standard input for a command. After getting that command I try to pass it into execvp so that it can carry out the command but it is not working. I think the problem is I am not sure how to pass it into execvp properly. It worked before with command line arguments but I cant get standard input working.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char* argv[])
{
int r;
char b1[4096];
char command[4096];
r = read(STDIN_FILENO, b1, 4096);
memcpy(command, b1, r);
command[r] = '\0';
//printf("%s\n", command);
char* progname = command;
//char* progname = argv[1];
pid_t pid;
if ((pid = fork()) < 0) perror("fork");
else if (pid == 0) { // child process
if (execvp(progname, argv + 1) == -1) {
perror("execvp");
return EXIT_FAILURE;
} // if
} // if
else {
fprintf(stderr, "Please specify the name of the program to exec as a command line argument\n");
return EXIT_FAILURE;
} // if
} // main

Pass array pointer to other program and extract that pointer in c

I am trying to pass an array of integer to other program and accept that from *argv. Then sort the array and print that from initial program. But I can not accept the pointer of the array and work with it. (can't even compile sort.c)
#include<stdio.h>
int main(int argc, char *argv[])
{
int arr = argv[1];
int temp = 0;
int length = sizeof(arr);
//Sort the array in descending order
for (int i = 0; i < length; i++) {
for (int j = i+1; j < length; j++) {
if(arr[i] < arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
int length = args-1;
int arr[length];
for(int i=0;i<length,i++)
{
arr[i]=argv[i+1];
}
int *p=arr
pid_t pid=fork();
if (pid==0) {
execv("sort",p);
}
else {
}
return 0;
}

Simple webserver unable to refetch web page. Page includes html and large css file like stat.st_size=22926

I have created a simple webserver, but I am unable to re-fetch the page twice. In server code my intention was to fetch as many times as the user prefers. I am fetching the page in Firefox browser. I am not saying there is anything wrong with the browser, but there may be problems with my code. So can anyone please tell me what could be the reason that my server is unable to render the page and css again. Is there any mistake in the response header? Why is browser unable to fetch the page?
This is the code:
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
//aaa
#define PORT 5000
#define BUF_SIZE 20000
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
int min(int a, int b)
{
return a>b?b:a;
}
int process(int size,char buffer[size],char status)
{
int i=0;
int line_len=0;
char *line=malloc(sizeof(char) *150);
while(i<size)
{
if(strncmp((void *)&buffer[i],"style9.css",strlen("style9.css"))==0)
return 3;
if(strncmp((void *)&buffer[i],"GET / HTTP/1.1",14)==0)
{
while(buffer[i]!='\n')
{
line[line_len]=buffer[i];
line_len++;
i++;
}
//line[line_len]='\0';
//printf("%s\n",line);
memset(line,0,line_len);
line_len=0;
return 2;
}
i++;
line_len++;
}
return 2;
}
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
off_t orig;
if (offset != NULL) {
/* Save current file offset and set offset to value in '*offset' */
orig = lseek(in_fd, 0, SEEK_CUR);
if (orig == -1)
return -1;
if (lseek(in_fd, *offset, SEEK_SET) == -1)
return -1;
}
size_t totSent = 0;
while (count > 0) {
size_t toRead = min(BUF_SIZE, count);
char buf[BUF_SIZE];
ssize_t numRead = read(in_fd, buf, toRead);
if (numRead == -1)
return -1;
if (numRead == 0)
break; /* EOF */
ssize_t numSent = write(out_fd, buf, numRead);
if (numSent == -1)
return -1;
if (numSent == 0) /* Should never happen */
printf("fatal: should never happen");
//fatal("sendfile: write() transferred 0 bytes");
count -= numSent;
totSent += numSent;
}
if (offset != NULL) {
/* Return updated file offset in '*offset', and reset the file offset
to the value it had when we were called. */
*offset = lseek(in_fd, 0, SEEK_CUR);
if (*offset == -1)
return -1;
if (lseek(in_fd, orig, SEEK_SET) == -1)
return -1;
}
return totSent;
}
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1000] = {0};
int get_return321;
//GET /css/style.css HTTP/1.1
char *hello = "HTTP/1.1 200 Okay\r\nContent-Type: text/html; charset=ISO-8859-4 \r\n\r\n";
//"HTTP/1.1 200 OK\\r\\n" \
"Content-Length: 55\r\n\n Content-Type: application/json\r\n '{\"name\":\"fawad\"}'";
//struct stat sb;
char *hello1 = "HTTP/1.1 200 Okay\r\nContent-Type: text/css\r\n\r\n";
struct stat sb_html;
struct stat sb_css;
int fd_in_html=open("/home/fawad/Desktop/C-work/html9.html",O_RDONLY);
const char* filename_html="/home/fawad/Desktop/C-work/html9.html";
int fd_in_css=open("/home/fawad/Desktop/C-work/css/style9.css",O_RDONLY);
const char* filename_css="/home/fawad/Desktop/C-work/css/style9.css";
if (stat(filename_html, &sb_html) == -1)
{
printf("%d\n",errno);
//exit(EXIT_FAILURE);
}
if (stat(filename_css, &sb_css) == -1)
{
printf("%d\n",errno);
//exit(EXIT_FAILURE);
}
printf("%lu\n",sb_css.st_size);
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
//exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt, sizeof(opt)))
{
perror("setsockopt");
//exit(EXIT_FAILURE);
}
/*if( setsockopt(server_fd, SOL_SOCKET, SO_SNDBUF, &sb.st_size, sizeof(sb.st_size)))
{
printf("sockopt\n");
}*/
/*int state = 1;
if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &state, sizeof(state)))
{
printf("sockopt\n");
}*/
int state = 1;
if(setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)))
{
printf("TCP CORK\n");
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if (bind(server_fd, (struct sockaddr *)&address,sizeof(address))<0)
{
perror("bind failed");
//exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
//exit(EXIT_FAILURE);
}
while(1)
{
printf("in loop\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
// exit(EXIT_FAILURE);
}
printf("request came\n");
valread = read( new_socket , buffer, (1000));
//printf("%s\n",buffer );
printf("_________________________________\n");
get_return321=process(900,buffer,'r');
buffer[499]='\0';
printf("\n");
printf("\n");
if(get_return321==2)
{
send(new_socket , hello , strlen(hello) , 0 );
//send(new_socket , buffer_html , sb_html.st_size , 0 );
sendfile(new_socket,fd_in_html,0,sb_html.st_size);
printf("html sent\n");
}
if(get_return321==3)
{
send(new_socket , hello1 , sb_css.st_size , 0 );
sendfile(new_socket,fd_in_css,0,sb_css.st_size);
printf("3 reached\n");
}
close(new_socket);
state = 0;
setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
//close(new_socket);
state = 1;
setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
}
//close(fd_in);
close(fd_in_html);
}
This is the output of running the program and sending a few requests from browser
user#fawad:Desktop/C-work# ./a.out
22926
in loop
request came
_________________________________
html sent
in loop
request came
_________________________________
3 reached
in loop
request came
_________________________________
html sent
in loop
request came
_________________________________
html sent
in loop
Killed
I have fixed it. I was not closing file descriptors so my current positions always stayed at the end of files in re-fetch attempts from firefox. Now working this is the full working code
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
//aaa
#define PORT 80
#define BUF_SIZE 20000
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
int min(int a, int b)
{
return a>b?b:a;
}
int process(int size,char buffer[size],char status)
{
int i=0;
int line_len=0;
char *line=malloc(sizeof(char) *150);
while(i<size)
{
if(strncmp((void *)&buffer[i],"style9.css",strlen("style9.css"))==0)
return 3;
if(strncmp((void *)&buffer[i],"GET / HTTP/1.1",14)==0)
{
while(buffer[i]!='\n')
{
line[line_len]=buffer[i];
line_len++;
i++;
}
//line[line_len]='\0';
//printf("%s\n",line);
memset(line,0,line_len);
line_len=0;
return 2;
}
i++;
line_len++;
}
return 2;
}
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
off_t orig;
if (offset != NULL) {
/* Save current file offset and set offset to value in '*offset' */
orig = lseek(in_fd, 0, SEEK_CUR);
if (orig == -1)
return -1;
if (lseek(in_fd, *offset, SEEK_SET) == -1)
return -1;
}
size_t totSent = 0;
while (count > 0) {
size_t toRead = min(BUF_SIZE, count);
char buf[BUF_SIZE];
ssize_t numRead = read(in_fd, buf, toRead);
if (numRead == -1)
return -1;
if (numRead == 0)
break; /* EOF */
ssize_t numSent = write(out_fd, buf, numRead);
if (numSent == -1)
return -1;
if (numSent == 0) /* Should never happen */
printf("fatal: should never happen");
//fatal("sendfile: write() transferred 0 bytes");
count -= numSent;
totSent += numSent;
}
if (offset != NULL) {
/* Return updated file offset in '*offset', and reset the file offset
to the value it had when we were called. */
*offset = lseek(in_fd, 0, SEEK_CUR);
if (*offset == -1)
return -1;
if (lseek(in_fd, orig, SEEK_SET) == -1)
return -1;
}
return totSent;
}
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1000] = {0};
int get_return321;
//GET /css/style.css HTTP/1.1
char *hello = "HTTP/1.1 200 Okay\r\nContent-Type: text/html; charset=ISO-8859-4 \r\n\r\n";
//"HTTP/1.1 200 OK\\r\\n" \
"Content-Length: 55\r\n\n Content-Type: application/json\r\n '{\"name\":\"fawad\"}'";
//struct stat sb;
char *hello1 = "HTTP/1.1 200 Okay\r\nContent-Type: text/css\r\n\r\n";
struct stat sb_html;
struct stat sb_css;
int fd_in_html;//=open("/home/fawad/Desktop/C-work/html9.html",O_RDONLY);
const char* filename_html="/home/fawad/Desktop/C-work/html9.html";
int fd_in_css;//=open("/home/fawad/Desktop/C-work/css/style9.css",O_RDONLY);
const char* filename_css="/home/fawad/Desktop/C-work/css/style9.css";
//printf("%lu\n",sb_css.st_size);
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
//exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt, sizeof(opt)))
{
perror("setsockopt");
//exit(EXIT_FAILURE);
}
/*if( setsockopt(server_fd, SOL_SOCKET, SO_SNDBUF, &sb.st_size, sizeof(sb.st_size)))
{
printf("sockopt\n");
}*/
/*int state = 1;
if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &state, sizeof(state)))
{
printf("sockopt\n");
}*/
int state = 1;
if(setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)))
{
printf("TCP CORK\n");
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if (bind(server_fd, (struct sockaddr *)&address,sizeof(address))<0)
{
perror("bind failed");
//exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
//exit(EXIT_FAILURE);
}
while(1)
{
printf("in loop\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
// exit(EXIT_FAILURE);
}
printf("request came\n");
valread = read( new_socket , buffer, (1000));
//printf("%s\n",buffer );
printf("_________________________________\n");
get_return321=process(900,buffer,'r');
buffer[499]='\0';
printf("\n");
printf("\n");
if(get_return321==2)
{
send(new_socket , hello , strlen(hello) , 0 );
//send(new_socket , buffer_html , sb_html.st_size , 0 );
fd_in_html=open("/home/fawad/Desktop/C-work/html9.html",O_RDONLY);
if (stat(filename_html, &sb_html) == -1)
{
printf("%d\n",errno);
//exit(EXIT_FAILURE);
}
sendfile(new_socket,fd_in_html,0,sb_html.st_size);
close(fd_in_html);
printf("html sent\n");
}
if(get_return321==3)
{
send(new_socket , hello1 , sb_css.st_size , 0 );
fd_in_css=open("/home/fawad/Desktop/C-work/css/style9.css",O_RDONLY);
if (stat(filename_css, &sb_css) == -1)
{
printf("%d\n",errno);
//exit(EXIT_FAILURE);
}
sendfile(new_socket,fd_in_css,0,sb_css.st_size);
printf("3 reached\n");
close(fd_in_css);
}
close(new_socket);
state = 0;
setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
//close(new_socket);
state = 1;
setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
}
//close(fd_in);
close(fd_in_html);
}

F-stack Client not Connecting to F-stack Server

I am trying to make tcp connection via F-stack over dpdk(19.08). The example given in F-stack package creates server but when i am trying to connect that port from same or another pc It is not responding anything.Still in netstat it is showing that server is listening but i am not able to connect from my client application. I tried client application with n without (eg Winshock Client app) F-stack but nothing good. Here is my F-stack Client code.
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <assert.h>
#include "ff_config.h"
#include "ff_api.h"
#include "ff_epoll.h"
#define MAX_EVENTS 512
struct epoll_event ev;
struct epoll_event events[MAX_EVENTS];
int epfd;
int sockfd;
char html[] =
"HTTP/1.1 200 OK\r\n"
"Server: F-Stack\r\n"
"Date: Sat, 25 Feb 2017 09:26:33 GMT\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 438\r\n"
"Last-Modified: Tue, 21 Feb 2017 09:44:03 GMT\r\n"
"Connection: keep-alive\r\n"
"Accept-Ranges: bytes\r\n"
"\r\n"
"<!DOCTYPE html>\r\n"
"<html>\r\n"
"<head>\r\n"
"<title>Welcome to F-Stack!</title>\r\n"
"<style>\r\n"
" body { \r\n"
" width: 35em;\r\n"
" margin: 0 auto; \r\n"
" font-family: Tahoma, Verdana, Arial, sans-serif;\r\n"
" }\r\n"
"</style>\r\n"
"</head>\r\n"
"<body>\r\n"
"<h1>Welcome to F-Stack!</h1>\r\n"
"\r\n"
"<p>For online documentation and support please refer to\r\n"
"F-Stack.org.<br/>\r\n"
"\r\n"
"<p><em>Thank you for using F-Stack.</em></p>\r\n"
"</body>\r\n"
"</html>";
struct sockaddr_in my_addr;
int loop(void *arg)
{
/* Wait for events to happen */
int nevents = ff_epoll_wait(epfd, events, MAX_EVENTS, 0);
int i;
for (i = 0; i < nevents; ++i) {
/* Handle new connect */
if (events[i].data.fd == sockfd) {
while (1) {
int nclientfd = ff_accept(sockfd, (struct linux_sockaddr *)&my_addr, sizeof(my_addr));
if (nclientfd < 0) {
break;
}
/* Add to event list */
ev.data.fd = nclientfd;
ev.events = EPOLLIN;
if (ff_epoll_ctl(epfd, EPOLL_CTL_ADD, nclientfd, &ev) != 0) {
printf("ff_epoll_ctl failed:%d, %s\n", errno,
strerror(errno));
break;
}
}
} else {
if (events[i].events & EPOLLERR ) {
/* Simply close socket */
ff_epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
ff_close(events[i].data.fd);
} else if (events[i].events & EPOLLIN) {
char buf[256];
size_t readlen = ff_read( events[i].data.fd, buf, sizeof(buf));
if(readlen > 0) {
ff_write( events[i].data.fd, html, sizeof(html) - 1);
} else {
ff_epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
ff_close( events[i].data.fd);
}
} else {
printf("unknown event: %8.8X\n", events[i].events);
}
}
}
}
int main(int argc, char * argv[])
{
ff_init(argc, argv);
sockfd = ff_socket(AF_INET, SOCK_STREAM, 0);
printf("sockfd:%d\n", sockfd);
if (sockfd < 0) {
printf("ff_socket failed\n");
exit(1);
}
int on = 1;
ff_ioctl(sockfd, FIONBIO, &on);
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(15231);
my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ret = ff_bind(sockfd, (struct linux_sockaddr *)&my_addr, sizeof(my_addr));
if (ret < 0) {
printf("ff_bind failed\n");
exit(1);
}
ret = (ff_connect(sockfd, (struct linux_sockaddr *)&my_addr, sizeof(my_addr)) == -1); //ff_connect
if (ret < 0) {
printf("ff_listen failed\n");
exit(1);
}
assert((epfd = ff_epoll_create(0)) > 0);
ev.data.fd = sockfd;
ev.events = EPOLLIN;
ff_epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
ff_run(loop, NULL);
return 0;
}

Issue porting Decryption from Windows CryptoAPI to linux libmcrypt

I am trying to port my program from Windows to Linux. The windows program uses Window CryptoAPI and linux is using libmcrypt.
Here is the Windows code:
#include <windows.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <exception>
using namespace std;
class CryptError:public exception{
public:
CryptError(){}
};
#define CHECK_RET(x) if(x == FALSE) {retval = GetLastError(); throw CryptError();};
LONG Decrypt(const string &key, std::vector<BYTE> &data){
LONG retval = 0;
try{
HCRYPTPROV hCrypt;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
CHECK_RET(CryptAcquireContext(&hCrypt, NULL, NULL, PROV_RSA_FULL, 0));
CHECK_RET(CryptCreateHash(hCrypt, CALG_MD5, 0, 0, &hHash));
CHECK_RET(CryptHashData(hHash, reinterpret_cast<const BYTE *>(key.c_str()), key.size(), 0));
CHECK_RET(CryptDeriveKey(hCrypt, CALG_RC2, hHash, MAKELPARAM(CRYPT_EXPORTABLE, 80), &hKey));
BYTE tempVal[200];
DWORD len = 200;
CryptGetKeyParam(hKey, KP_EFFECTIVE_KEYLEN, tempVal, &len, 0);
len = 200;
CryptGetKeyParam(hKey, KP_MODE, tempVal, &len, 0);
len = 200;
CryptExportKey(hKey, NULL, PLAINTEXTKEYBLOB, 0, tempVal, &len);
len = 200;
CryptGetKeyParam(hKey, KP_IV, tempVal, &len, 0);
DWORD count = data.size();
CHECK_RET(CryptDecrypt(hKey, 0, TRUE, 0, &(data[0]), &count));
data.resize(count);
}catch(CryptError &e){
}
return retval;
}
int main(void){
BYTE data[9] = {0xdc,0x3d,0x96,0x23,0x29,0xdd,0x1b,0x2f, 0};
vector<BYTE> vData(data, data + 8);
Decrypt("PNEMAIL", vData);
cerr << "vData: ";
int len = vData.size();
for(int i = 0; i < len; i++){
if(i > 0)
cerr << ',';
cerr << hex << setw(2) << setfill('0') << (int)(vData[i]);
}
cerr << endl;
return 0;
}
When the program is run, it returns:
vData: 42,46,30,41,43,34,31
The Q&D linux version looks like this:
#include <mcrypt.h>
#include <iostream>
#include <iomanip>
#include <string>
#include <openssl/md5.h>
#include <stdint.h>
#include <stdexcept>
#include <vector>
#include <valarray>
#include <memory.h>
using namespace std;
class MCrypt{
private:
MCRYPT mcrypt;
public:
MCrypt(char *algorithm, char* algorithm_directory, char *mode, char* mode_directory){
mcrypt = mcrypt_module_open(algorithm, algorithm_directory, mode, mode_directory);
if(mcrypt == MCRYPT_FAILED)
throw runtime_error("MCrypt init failed");
}
int init(void *key, int lenofkey, void *IV){
return mcrypt_generic_init(mcrypt, key, lenofkey, IV);
}
int enc_get_iv_size(){
return mcrypt_enc_get_iv_size(mcrypt);
}
int deinit(){
return mcrypt_generic_deinit(mcrypt);
}
int decrypt(void *data, int len){
mdecrypt_generic(mcrypt, data, len);
}
~MCrypt(){
deinit();
mcrypt_module_close(mcrypt);
}
};
#ifdef DEBUG
void inline printArrayFunc(const char *start, const uint8_t *data, int len){
// DEBUG: print value of $key1
cerr << start;
for(int i = 0; i < len; i++){
if(i > 0)
cerr << ',';
cerr << hex << setw(2) << setfill('0') << (int)(data[i]);
}
cerr << endl;
}
#define printArray(start, data, len) printArrayFunc(start, data, len)
#else
#define printArray(start, data, len)
#endif
int main(void){
uint8_t data[8] = {0xdc,0x3d,0x96,0x23,0x29,0xdd,0x1b,0x2f};
const char *sKey1 = "PNEMAIL";
const int key1Len = 7;
uint8_t *dataPtr = &(data[0]);
uint8_t key1[17];
key1[16] = 0;
// Hash sKey1
MD5(reinterpret_cast<const unsigned char *>(sKey1), key1Len, key1);
MCrypt mcrypt(MCRYPT_RC2, NULL, MCRYPT_CBC, NULL);
vector<uint8_t> iv(mcrypt.enc_get_iv_size(), 0);
// Use the first 80-bits of key1
mcrypt.init(key1, 10, &(iv[0]));
mcrypt.decrypt(dataPtr, 8);
printArray("vData: ", dataPtr, 8);
return 0;
}
When the program is run, it returns:
vData: 4d,3d,82,71,88,d2,d5,4b
I've check that both programs are using the same data.
CryptDeriveKey creates a key 07,f1,e2,ea,d4,c8,79,74,03,a6 (according to CryptExportKey), the same as the first 10 bytes of the md5 generated in Linux (which I shorten to match the requested 80-bit key).
Neither are using a salt on the algorithm (or at least are not reporting as such)
They are both using an 8-byte IV of {0,0,0,0,0,0,0,0}
They are both using the RC2 algorithm
They are both using CBC mode
I cannot figure out why they are returning different data. Any assistance would be greatly appreciated.

Resources