LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   error: dereferencing pointer to incomplete type (https://www.linuxquestions.org/questions/programming-9/error-dereferencing-pointer-to-incomplete-type-4175415405/)

joyce092130 07-07-2012 09:26 AM

error: dereferencing pointer to incomplete type
 
hi everyone!
im working on my client/server chat program and i had "error: dereferencing pointer to incomplete type" during the compilation of my clientchat.c

Here is the code:

#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>

int main(int argc,char *argv[])
{
struct sockaddr_in clientaddr;
pid_t pid;
int clientfd,sendbytes;
struct hostent *host;
char *buf,*buf_r;

if(argc < 4)
{
printf("usage:\n");
printf("%s host port name\n",argv[0]);
exit(1);
}

host = gethostbyname(argv[1]);
if((clientfd = socket (AF_INET,SOCK_STREAM,0)) == -1)
{
perror("socket\n");
exit(1);
}
clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons((uint16_t)atoi(argv[2]));
clientaddr.sin_addr = *((struct in_addrr *) host->h_addr);
bzero(&(clientaddr.sin_zero),0);
if(connect(clientfd,(struct sockaddr *)&clientaddr,sizeof(struct sockaddr)) == -1)
{
perror("connect\n");
exit(1);
}

buf=(char *)malloc(120);
memset(buf,0,120);

buf_r=(char *)malloc(100);

if( recv(clientfd,buf,100,0) == -1)
{
perror("recv: ");
exit(1);
}
printf("\n%s\n",buf);

pid = fork();

while(1)
{
if(pid > 0)
{
//get_cur_time(time_str);

strcpy(buf,argv[3]);
strcat(buf,":");
memset(buf_r,0,100);
//gets(buf_r);
fgets(buf_r,100,stdin);
strncat(buf,buf_r,strlen(buf_r)-1);
//strcat(buf,time_str);
//printf("---%s\n",buf);
if((sendbytes = send(clientfd,buf,strlen(buf),0)) == -1)
{
perror("send\n");
exit(1);
}
}
else if(pid == 0)
{
memset(buf,0,1000);
if(recv(clientfd,buf,100,0) <=0)
{
perror("recv:");
close(clientfd);
raise(SIGSTOP);
exit(1);
}
printf("%s\n",buf);
}
else
perror("fork");
}
close(clientfd);
return 0;
}

Please help me with this.
Thank u much.

johnsfine 07-07-2012 09:35 AM

Quote:

Originally Posted by joyce092130 (Post 4721540)
clientaddr.sin_addr = *((struct in_addrr *) host->h_addr);

Is the extra r on that line a typo?

Without that r your code compiles.

AwesomeMachine 07-07-2012 09:47 AM

One of the header prototypes is probably not coded exactly the way the compiler wants it. I think there is a "no deference" switch for gcc and g++ that you could try. I'm not able to locate the exact code, because I need more context from the compiler, and preferably some debug traces.

I have a hunch uint16 type is a culprit. Try using that header from the kernel headers instead of the libc6 one.

joyce092130 07-07-2012 10:48 AM

thank u so much. no more errors on both my clientchat.c and serverchat.c but why is it that there is still no exe file. it is supposed to have a chat program between the client and the server.

when i tried

./clientchat acer-d56ca9a39d 350

the result is -bash: ./clientchat: No such file or directory

same result i got for serverchat

pan64 07-07-2012 10:59 AM

how did you compile your code? What was the command line?

joyce092130 07-07-2012 11:02 AM

using cygwin terminal i compiled my serverchat as:
gcc -Wall -o server serverchat.c

and my clientchat as
gcc -Wall -o client clientchat.c

there were no errors displayed alr

pan64 07-07-2012 11:07 AM

so your server program is server (instead or serverchat), your client program is client (instead of clientchat).
The name of the created program is the string after the -o option. see the man page of gcc...

joyce092130 07-07-2012 11:10 AM

where can i check on that?

pan64 07-07-2012 01:01 PM

man g++
Quote:

-o file
Write output to file. This is the same as specifying file as the second non-option argument to cpp. gcc has a different interpretation of a second non-option argument, so you must use -o to specify the output file

joyce092130 07-07-2012 08:41 PM

so what shall i do to make my program an exe file. so that i can have the expected chat between the server and the client.

joyce092130 07-07-2012 08:44 PM

How can i make my codes in hello world program into a single chat program where the client can send messages to the server and the server can send replies to the client?

here are my codes for the hello world program:

server.c


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

int _GetHostName(char *buffer, int length);

const char MESSAGE[]="Hello, World!\n";
const int BACK_LOG=5;

int main(int argc, char *argv[]){
int serverSocket=0,on=0,port=0,status=0,childPid=0;
struct hostent *hostPtr=NULL;
char hostname[80]="";
struct sockaddr_in serverName={0};

if(2!=argc){
fprintf(stderr,"Usage: %s <port>\n",argv[0]);
exit(1);
}
port=atoi(argv[1]);
serverSocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(-1==serverSocket){
perror("socket()");
exit(1);
}

on=1;
status=setsockopt(serverSocket,SOL_SOCKET,SO_REUSEADDR,
(const char*)&on,sizeof(on));
if(-1==status){
perror("setsockopt(...,SO_REUSEADDR,...)");
}
{
struct linger linger={0};
linger.l_onoff=1;
linger.l_linger=30;
status=setsockopt(serverSocket,SOL_SOCKET,SO_LINGER,
(const char*)&linger,sizeof(linger));
if(-1==status){
perror("setsockopt(...,SO_LINGER,...)");
}
}

status=_GetHostName(hostname,sizeof(hostname));
if(-1==status){
perror("_GetHostName()");
exit(1);
}

hostPtr=gethostbyname(hostname);
if(NULL==hostPtr){
perror("gethostbyname()");
exit(1);
}

(void)memset(&serverName,0,sizeof(serverName));
(void)memcpy(&serverName.sin_addr,hostPtr->h_addr,hostPtr->h_length);

serverName.sin_family=AF_INET;
serverName.sin_port=htons(port);

status=bind(serverSocket,(struct sockaddr*)&serverName,sizeof(serverName));
if(-1==status){
perror("bind()");
exit(1);
}

status=listen(serverSocket,BACK_LOG);
if(-1==status){
perror("listen()");
exit(1);
}

for(;{
struct sockaddr_in clientName={0};
int slaveSocket, clientLength=sizeof(clientName);

(void)memset(&clientName,0,sizeof(clientName));

slaveSocket=accept(serverSocket,
(struct sockaddr*)&clientName,&clientLength);
if(-1==slaveSocket){
perror("accept()");
exit(1);
}

childPid=fork();

switch(childPid){

case -1:/*ERROR */
perror("fork()");
exit(1);
case 0 :/*child process */
close(serverSocket);
if(-1==getpeername(slaveSocket,
(struct sockaddr*)&clientName,&clientLength)){
perror("getpeername()");
}else{
printf("Connection request from %s\n",
inet_ntoa(clientName.sin_addr));
}

write(slaveSocket,MESSAGE,strlen(MESSAGE));
close(slaveSocket);
exit(0);
default:/*parent process */
close(slaveSocket);
}
}
return 0;
}

int _GetHostName(char *buffer,int length){
struct utsname sysname={0};
int status=0;

status=uname(&sysname);
if(-1!=status){
strncpy(buffer,sysname.nodename,length);
}
return(status);
}

------
client.c


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(int argc,char *argv[]){
int clientSocket,remotePort,status=0;
struct hostent *hostPtr=NULL;
struct sockaddr_in serverName={0};
char buffer[256]="";
char *remoteHost=NULL;

if(3!=argc){
fprintf(stderr,"Usage: %s <serverHost> <serverPort>\n",argv[0]);
exit(1);
}
remoteHost=argv[1];
remotePort=atoi(argv[2]);
clientSocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(-1==clientSocket){
perror("socket()");
exit(1);
}

hostPtr=gethostbyname(remoteHost);
if(NULL==hostPtr){
hostPtr=gethostbyaddr(remoteHost,strlen(remoteHost),AF_INET);
if(NULL==hostPtr){
perror("Error resolving server address ");
exit(1);
}
}
serverName.sin_family=AF_INET;
serverName.sin_port=htons(remotePort);
(void)memcpy(&serverName.sin_addr,hostPtr->h_addr,hostPtr->h_length);
status=connect(clientSocket,(struct sockaddr*)&serverName,
sizeof(serverName));
if(-1==status){
perror("connect()");
exit(1);
}

while(0<(status=read(clientSocket,buffer,sizeof(buffer)-1)))
printf("%d: %s",status,buffer);
if(-1==status)perror("read()");
close(clientSocket);
return 0;
}

thank u!

KernelJay 09-29-2012 09:06 AM

Hi Joyce,
Please be advised that your posted code sample contains a likely heap-based buffer overflow which an attacker might be able to leverage to exploit the system. Use of strcpy() should be limited to instances where the source buffer is not user-controlled or has already been bounds checked. strncpy(buf, argv[3], 120) would prevent this type of attack in the event that argv[3] does not null terminate within 120 bytes.

For more information on how this could compromise your system, please check out my blog regarding stack-based buffer overflows which are even more dangerous. (Heap based overflows can certainly still lead to code execution and crashes.)

VERT Vuln School: Stack Buffer Overflows 101

Part 1: Introducing the Bug
Part 2: Explaining the Stack
Part 3: Exploiting the Bug

Regards,
Craig


All times are GMT -5. The time now is 06:14 PM.