I'm getting the following compiler warning each time I try and compile an application I'm building:
└─$ gcc -o svr2 common.h launch.c tools.c netops.c
netops.c: In function ‘acceptClient’:
netops.c:138:33: warning: implicit declaration of function ‘displayMenu’ [-Wimplicit-function-declaration]
138 | displayMenu(clnFd);
| ^~~~~~~~~~~
The application consists of 4 files:
- Common.h - function prototypes and defines
- Launch.c - main entry point
- Netops.c - Networking functions
- Tools.c - Tools that the server will provide
All .c files have #include "common.h"
as their first line. Can someone please have a look and see why it thinks I'm implicitly declaring this function? (If there is any vulnerable code ignore it as this is going to be a CTF binary).
Code base as follows (most code left out for brevity or is incomplete at present):
common.h
#ifndef _COMMON_H_
#define _COMMON_H_
/* System includes here */
/* List of defines here */
/* Function prototypes */
int launchServer();
int acceptClient(int);
int writeToClient(int, char *);
int readFromClient(int, char *);
int b64Encoder(int);
int checkPassword(int);
int printFlag();
int b64Decode(int);
void displayMenu(int);
#endif /* _COMMON_H_ */
netops.c
#include "common.h"
// Some code omitted here
//...
int acceptClient(int svrFd)
{
struct sockaddr_in cln;
int result = 0;
int clnFd = 0;
int clnPort = 0;
int pid = 0;
socklen_t len = 0;
char *clnIp;
// Attempt to accept incoming client
len = sizeof(cln);
for(;;)
{
clnFd = accept(svrFd, (struct sockaddr *)&cln, &len);
if(SOCKERR == clnFd)
{
fprintf(stderr, "[-] Unable to accept incoming client. Error is: %s (%d).\n", strerror(errno), errno);
close(clnFd);
continue;
}
clnIp = inet_ntoa(cln.sin_addr);
clnPort = ntohs(cln.sin_port);
fprintf(stdout, "[*] New connection from client: %s:%d.\n", clnIp, clnPort);
// Set client socket to non-blocking
result = fcntl(clnFd, F_SETFL, fcntl(clnFd, F_GETFL) | O_NONBLOCK);
if(FCNTLERR == result)
{
fprintf(stderr, "[-] Unable to set the client port to non-blocking. Attempting to continue. Error is: %s (%d).\n", strerror(errno), errno);
}
pid = fork();
if(pid < 0)
{
// Unable to fork
fprintf(stderr, "[-] Unable to fork new process for %s:%d. Error is: %s (%d).\n", clnIp, clnPort, strerror(errno), errno);
close(clnFd);
continue;
}
if(pid == 0)
{
// This is the client process
fprintf(stdout, "[*] Forked new process for client: %s:%d.\n", clnIp, clnPort);
result = checkPassword(clnFd);
if(CLNERR == result)
{
close(clnFd);
return CLNERR;
}
if(CLNCLOSE == result)
{
fprintf(stderr, "[-] Client connection %s:%d closed.\n", clnIp, clnPort);
close(clnFd);
continue;
}
if(PASSCOUNTEXCEED == result)
{
fprintf(stderr, "[-] Client %s:%d exceeded the maximum password attempts allowed.\n", clnIp, clnPort);
close(clnFd);
continue;
}
if(SUCCESS == result)
{
// FUNCTION CALLED HERE
displayMenu(clnFd);
}
}
}
// Should never hit here. If it does, it means we have broken out of the while loop for an unknown reason.
close(clnFd);
return CLNERR;
}
//...
// Some code omitted here
tools.c
#include "common.h"
int b64Encode(int clnFd)
{
//...
return SUCCESS;
}
int b64Decode(int clnFd)
{
return 0;
}
void displayMenu(int clnFd)
{
// FUNCTION CODE HERE
int result = SUCCESS;
result = b64Encode(clnFd);
}
int checkPassword(int clnFd)
{
int passCount = 0;
int clnWr = SUCCESS;
int clnRd = SUCCESS;
int result = SUCCESS;
ssize_t len = 0;
char *readBuff;
char *writeBuff;
char *writeText;
const char *correctPwd = "************";
// Malloc 1024 bytes to both read and write buffers
readBuff = (char *)malloc(R_BUFLEN * sizeof(char));
writeBuff = (char *)malloc(W_BUFLEN * sizeof(char));
// Request the password
writeText = "Enter the server password to continue";
snprintf(writeBuff, W_BUFLEN, "%s (Attempt %d of %d): ", writeText, passCount+1, MAXPASSCOUNT);
clnWr = writeToClient(clnFd, writeBuff);
memset(writeBuff, ZEROBUF, (W_BUFLEN * sizeof(*writeBuff)));
if(SUCCESS != clnWr)
{
free(readBuff);
free(writeBuff);
return CLNERR;
}
// Read incoming password
for(;;)
{
clnRd = readFromClient(clnFd, readBuff);
if(READERR == clnRd)
{
free(readBuff);
free(writeBuff);
return CLNERR;
}
if(CLNCLOSE == clnRd)
{
free(readBuff);
free(writeBuff);
return CLNCLOSE;
}
if(SUCCESS == clnRd)
{
if(strncmp(correctPwd, readBuff, PASSLEN) == MATCH)
{
writeText = "Correct password supplied! Welcome to the server.\n";
snprintf(writeBuff, W_BUFLEN, "%s", writeText);
clnWr = writeToClient(clnFd, writeBuff);
memset(writeBuff, ZEROBUF, (W_BUFLEN * sizeof(*writeBuff)));
if(SUCCESS != clnWr)
{
free(readBuff);
free(writeBuff);
return CLNERR;
}
free(readBuff);
free(writeBuff);
return SUCCESS;
}
else
{
passCount++;
if(MAXPASSCOUNT == passCount)
{
writeText = "Maximum attempts reached. Goodbye!\n";
snprintf(writeBuff, W_BUFLEN, "%s", writeText);
clnWr = writeToClient(clnFd, writeBuff);
memset(writeBuff, ZEROBUF, (W_BUFLEN * sizeof(*writeBuff)));
if(SUCCESS != clnWr)
{
free(readBuff);
free(writeBuff);
return CLNERR;
}
return PASSCOUNTEXCEED;
}
else
{
writeText = "Incorrect password supplied.\nEnter the server password to continue";
snprintf(writeBuff, W_BUFLEN, "%s (Attempt %d of %d): ", writeText, passCount+1, MAXPASSCOUNT);
clnWr = writeToClient(clnFd, writeBuff);
memset(writeBuff, ZEROBUF, (W_BUFLEN * sizeof(*writeBuff)));
if(SUCCESS != clnWr)
{
free(readBuff);
free(writeBuff);
return CLNERR;
}
}
}
}
}
// Should never hit here. If it does, it means an unknown error has occurred.
free(readBuff);
free(writeBuff);
return CLNERR;
}
launch.c
#include "common.h"
int main(int argc, char *argv[])
{
int svrFd = 0;
int clnFd = 0;
// Start the server
svrFd = launchServer();
if(SVRERR == svrFd)
{
fprintf(stderr, "[-] Fatal server error. Exiting.");
return GENERR;
}
// Accept incoming clients
clnFd = acceptClient(svrFd);
if(CLNERR == clnFd)
{
fprintf(stderr, "[-] Fatal client error. Exiting.");
return GENERR;
}
return 0;
}