0% found this document useful (0 votes)
3 views38 pages

Socket

The document describes a Security Enhanced File Transfer Tool (SEFT) for Linux, which integrates security checks into the traditional File Transfer Protocol (FTP) to ensure secure data transmission between client and server. It highlights the advantages of using Linux for its performance, flexibility, and security, and explains the workings of FTP, including its connection modes and inherent security vulnerabilities. The SEFT tool enhances security by requiring authentication for file transfers and provides commands for opening connections, downloading, uploading, and closing connections.

Uploaded by

priji.photodumps
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views38 pages

Socket

The document describes a Security Enhanced File Transfer Tool (SEFT) for Linux, which integrates security checks into the traditional File Transfer Protocol (FTP) to ensure secure data transmission between client and server. It highlights the advantages of using Linux for its performance, flexibility, and security, and explains the workings of FTP, including its connection modes and inherent security vulnerabilities. The SEFT tool enhances security by requiring authentication for file transfers and provides commands for opening connections, downloading, uploading, and closing connections.

Uploaded by

priji.photodumps
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Security Enhanced File Transfer Tool for Linux

Introduction:

The introduction of Linux in the cyber world has given relief to the system
administrators because of its security features. It has got rich features for the networking
and the security. One of the oldest and well-known technique to transfer the data is File
Transfer Protocol. In this project we have equipped a model FTP with a security check
tool, which allows the communication between the client and the server only after
performing the security check, in the form of user name and password. This project helps
us to have a secured way of the data transmission using sockets in Linux.

Why Linux? :

Performance:
Linux is efficient and fast, and makes excellent use of hardware. Fast and
responsive the system is, even with many processes running and with multiple windows
open. Linux is commonly used in high-end server environments where this kind of
hardware is the norm. Linux is used for building large "clusters" consisting of hundreds
of machines connected with a fast network, used f or massive scientific calculations or
for driving large web sites.

Flexibility and Free:


Since its licensed under GNU its code is open so each and every user can access
even the internal parts of the code for free of cost and he can modify it as per his/ her
needs. Adding modules can modify even the kernel, which is said to be the core of the
operating system.

Secured:
This is supposed to be the most secured at almost free of cost operating system
that ever created. And it’s free from viruses, worms, and Trojans. It’s secured from the
virus in the “.exe” format because these files are not executed in Linux.

Why FTP? :

FTP is implemented using TCP and Advantages of TCP over UDP is as follows.

Transmission Control Protocol (TCP):

TCP provides connections between clients and servers. A TCP


client establishes a connection with a given server, exchanges data with that server
across the connection, and then terminates the connection.

5
TCP also provides reliability. When TCP sends data to the other
end, it requires an acknowledgment in return. If an acknowledgment is not received, TCP
automatically retransmits the data and waits a longer amount of time. After some number
of retransmissions, TCP will give up, with the total amount of time spent trying to send
data typically between 4 and10 minutes (depending on the implementation).It delivers
data to the other endpoint if possible, and notifies the user (by giving up on
retransmissions and breaking the connection) if it is not possible. Therefore, TCP cannot
be described as a 100% reliable protocol; It provides reliable delivery of data or reliable
notification of failure. TCP contains algorithms to estimate the round-trip time
(RTT) between a client and server dynamically so that it knows how long to
wait for an acknowledgment.

FTP:

In FTP two types of connections are established between client & server. Data
connection & control connection. Data connection is used to transfer data while control
connection is used to transfer commands. Control link is always there whether data is
being transmitted or not while data link is released on the completion of data transfer.

FTP runs exclusively over TCP. It defaults to listen on port 21 for incoming
connections from FTP clients. A connection to this port from the FTP Client forms the
control stream on which commands are passed from the FTP client to the FTP server and
on occasion from the FTP server to the FTP client. FTP uses out-of-band control, which
means it uses a separate connection for control and data. Thus, for the actual file transfer
to take place, a different connection is required which is called the data stream.
Depending on the transfer mode, the process of setting up the data stream is different.
Port 21 for control (or program), port 20 for [Link] this project is a model
implementaion of the FTP protocol so we have used a different port number those are
unused and free to user for the command and data.

In active mode, the FTP client opens a dynamic port, sends the FTP server the
dynamic port number on which it is listening over the control stream and waits for a
connection from the FTP server. When the FTP server initiates the data connection to the
FTP client it binds the source port to port 20 on the FTP server.

In order to use active mode, the client sends a PORT command, with the IP and
port as argument. The format for the IP and port is "h1,h2,h3,h4,p1,p2". Each field is a
decimal representation of 8 bits of the host IP, followed by the chosen data port. For
example, a client with an IP of [Link], listening on port 49154 for the data
connection will send the command "PORT 192,168,0,1,192,2". The port fields should be
interpreted as p1×256 + p2 = port, or, in this example, 192×256 + 2 = 49154.

In passive mode, the FTP server opens a dynamic port, sends the FTP client the
server's IP address to connect to and the port on which it is listening (a 16-bit value
broken into a high and low byte, as explained above) over the control stream and waits

6
for a connection from the FTP client. In this case, the FTP client binds the source port of
the connection to a dynamic port.

To use passive mode, the client sends the PASV command to which the server
would reply with something similar to "227 Entering Passive Mode (127,0,0,1,192,52)".
The syntax of the IP address and port are the same as for the argument to the PORT
command.

In extended passive mode, the FTP server operates exactly the same as passive
mode, however it only transmits the port number (not broken into high and low bytes)
and the client is to assume that it connects to the same IP address that was originally
connected to. Extended passive mode was added by RFC 2428 in September 1998.

While data is being transferred via the data stream, the control stream sits idle.
This can cause problems with large data transfers through firewalls which time out
sessions after lengthy periods of idleness. While the file may well be successfully
transferred, the control session can be disconnected by the firewall, causing an error to be
generated.

In ASCII mode (see below), resuming transfers can be troublesome if client and server
use different end of line characters.

The objectives of FTP, as outlined by its RFC, are:

1. To promote sharing of files (computer programs and/or data).


2. To encourage indirect or implicit use of remote computers.
3. To shield a user from variations in file storage systems among different hosts.
4. To transfer data reliably, and efficiently.

7
Security problems:
The original FTP specification is an inherently insecure method of transferring
files because there is no method specified for transferring data in an encrypted fashion.
This means that under most network configurations, user names, passwords, FTP
commands and transferred files can be "sniffed" or viewed by anyone on the same
network using a packet sniffer. This is a problem common to many Internet protocol
specifications written prior to the creation of SSL such as HTTP, SMTP and Telnet. The
common solution to this problem is to use either SFTP (SSH File Transfer Protocol), or
FTPS (FTP over SSL), which adds SSL or TLS encryption to FTP as specified in RFC
4217

Data format of FTP:


While transferring data over the network, several data representations can be used.
The two most common transfer modes are:

1. ASCII mode
2. Binary mode: In "Binary mode", the sending machine sends each file byte for
byte and as such the recipient stores the bytestream as it receives it. (The FTP
standard calls this "IMAGE" or "I" mode)

In "ASCII mode", any form of data that is not plain text will be corrupted. When a
file is sent using an ASCII-type transfer, the individual letters, numbers, and characters
are sent using their ASCII character codes. The receiving machine saves these in a text
file in the appropriate format (for example, a Unix machine saves it in a Unix format, a
Windows machine saves it in a Windows format). Hence if an ASCII transfer is used it
can be assumed plain text is sent, which is stored by the receiving computer in its own
format. Translating between text formats might entail substituting the end of line and end
of file characters used on the source platform with those on the destination platform, e.g.
a Windows machine receiving a file from a Unix machine will replace the line feeds with
carriage return-line feed pairs. It might also involve translating characters; for example,
when transferring from an IBM mainframe to a system using ASCII, EBCDIC characters
used on the mainframe will be translated to their ASCII equivalents, and when
transferring from the system using ASCII to the mainframe, ASCII characters will be
translated to their EBCDIC equivalents.

By default, most FTP clients use ASCII mode. Some clients try to determine the required
transfer-mode by inspecting the file's name or contents, or by determining whether the
server is running an operating system with the same text file format.

The FTP specifications also list the following transfer modes:

8
1. EBCDIC mode - this transfers bytes, except they are encoded in EBCDIC rather
than ASCII. Thus, for example, the ASCII mode server
2. Local mode - this is designed for use with systems that are word-oriented rather
than byte-oriented. For example mode "L 36" can be used to transfer binary data
between two 36-bit machines. In L mode, the words are packed into bytes rather
than being padded. Given the predominance of byte-oriented hardware nowadays,
this mode is rarely used. However, some FTP servers accept "L 8" as being
equivalent to "I".

In practice, these additional transfer modes are rarely used. They are however still used
by some legacy mainframe systems.

The text (ASCII/EBCDIC) modes can also be qualified with the type of carriage control
used (e.g. TELNET NVT carriage control, ASA carriage control), although that is rarely
used nowadays.

Note that the terminology "mode" is technically incorrect, although commonly used by
FTP clients. "MODE" in RFC 959 refers to the format of the protocol data stream
(STREAM, BLOCK or COMPRESSED), as opposed to the format of the underlying file.
What is commonly called "mode" is actually the "TYPE", which specifies the format of
the file rather than the data stream. FTP also supports specification of the file structure
("STRU"), which can be either FILE (stream-oriented files), RECORD (record-oriented
files) or PAGE (special type designed for use with TENEX). PAGE STRU is not really
useful for non-TENEX systems, and RFC1123 section [Link] recommends that it not be
implemented.

Why SEFT tool?:


This project is used for the safe transfer of a file from server to client or vice
versa. Even when the server and the client are connected to each other has to be some
authentication for the transfer of file and that’s the security enhancement that has been
made in this project. This will ask for the authentication from the client who is helpful to
make the connection secured and if authentication fails for even one time then the
connection established will be disconnected from the server side. Client can give its
choice in the form of command to server and server will respond accordingly.

In this tool we have basically used 4 commands those are helpful in the transfer of
file like
1. Open
2. Help
3. Download from client (Get)
4. Upload to server (put)
5. Terminating the connection (close)

9
Open:
This is the first basic command that has to be given to open the communication
channel between the client and the server.

“ftp> open”

Help:
To get the help from the server the help command has to be used on giving this
command will take the help file from the server and give it to the client end.

Download from client (get):

This command is used to download any file from the server to the client side. On
giving this command this will ask for the file name that you want to search for from the
server. Once if it got the file it will give you or it will return an error. The actual process
that’s happening here is it taken a copy of the file from the server side and it create a file
in the client side wit the same permission. The copy of the file that’s been taken will be
there in the data socket it will be written to the created file.

Uploading to the server (put):

This command performs the inverse job of the get command that’s it will upload
the particular file to the server side. First it will create a create a file of the same name`
and the then it will read the contents of the file and store it in a particular buffer and then
the buffer will be transmitted and stored in the server side.

Terminating the connection (close):

This command will close or terminate the connection between the sockets. That is
it will close the entire opened socket. And send FIN signal to the client.

So using our SEFTP tool one of the security problem that we will face in the
server side like password for the file transfer can be implemented. This will not be a
completely secured way of transfer of the file but it will help you to increase the security
level of the server.

10
Introduction to Socket:
Communication within the processes of a computer can be easily done with the
help of the pipes and other shared memories, but while communicating between the
computers on a network we need socket. A socket is basically nothing but a buffer that is
used to store the commands and data. Each and every socket is assigned with a particular
port number. The sockets on the client and the server side having the same port number
will communicate with each other.

Rlogin and ftp usually use sockets to communicate.

11
Sockets are created and used differently from pipes because they make a clear
distinction between client and server. The socket mechanism can implement multiple
clients attached to a single server.

Socket Connections we can think of socket connections as telephone calls into a


busy building. A call comes into an organization and is answered by a receptionist who
puts the call through to the correct department (the server process) and from there to the
right person (the server socket). Each incoming call (client) is routed to appropriate end
point and the intervening operators are free to deal with further calls. Before you look at
the way socket connections are established in Linux systems, you need to understand how
they operate for socket applications that maintain a connection.
1)
First of all, a server application creates a socket, which like a file descriptor is a resource
assigned to the server process and that process alone. The server creates it using the
system call socket, and it can’t be shared with other processes.
2)
Next, the server process gives the socket a name. Local sockets are given a filename in
the Linux file system often to be found in /tmp or /usr/tmp. For network sockets, the
filename will be a service identifier(port number/access point) relevant to the particular
network to which the clients can connect. This identifier allows Linux to route incoming
connections specifying a particular port number to the correct
server process. A socket is named using the system call bind. The server process then
waits for a client to connect to the named socket.
3)
The system call, listen, creates a queue for incoming connections.
4)
The server can accept them using the system call accept .When the server calls accept, a
new socket is created that is distinct from the named socket. This new socket is used
solely for communication with this particular client. The named socket remains for
further connections from other clients. The server can take advantage of multiple
connections. For a simple server, further clients wait on the listen queue until the server is
ready again.
5)
The client side of a socket-based system is more straightforward. The client creates an
unnamed socket by calling socket. It then calls connect to establish a connection with the
server by using the server’s named socket as an address.
Once established, sockets can be used like low-level file descriptors, providing two-way
data communications.

12
Some API’s used for implementation of socket
programming.

Socket Function:
To perform network I/O, the first thing a process must do is call the socket
function, specifying the type of communication protocol desired (TCP using IPv4, UDP
using IPv6, Unix domain stream protocol, etc.).Family specifies the protocol family. The
argument is often referred to as domain instead of family. The socket type is one of the
constant only. The protocol argument to the socket function should be set to the specific
protocol type or 0 to select the system's default for the given
combination of family and type.

#include <sys/socket.h>
int socket (int family, int type, int protocol);

It returns a non negative value during the successful creation of the socket and -1 on the
failure.

Protocol family constants for socket function

type of socket for socket function

protocol of sockets for AF_INET or AF_INET6

13
Combinations of family and type for the socket function

connect Function :
The connect function is used by a TCP client to establish a connection with a TCP
server. sockfd is a socket descriptor returned by the socket function. The second and third
arguments are a pointer to a socket address structure and its size. The socket address
structure must contain the IP address and port number of the server.

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
The function will return 0 on success and –1 in case of the failure.

The client does not have to call bind before calling connect: the kernel will choose
both an ephemeral port and the source IP address if necessary. In the case of a TCP
socket, the connect function initiates TCP's three-way handshake the function returns
only when the connection is established or an error occurs. There are several different
error returns possible. 1. If the client TCP receives no response to its SYN segment,
ETIMEDOUT is returned. 4.4BSD, for example, sends one SYN when connect is called,
another 6 seconds later, and another 24 seconds later If no response is received after a
total of 75 seconds, the error is returned. Some systems provide administrative control
over this timeout. If the server's response to the client's SYN is a reset (RST), this
indicates that no process is waiting for connections on the server host at the port specified
This is a hard error and the error ECONNREFUSED is returned to the client as soon as
the RST is received. An RST is a type of TCP segment that is sent by TCP when
something is wrong. Three conditions that generate an RST are: when a SYN arrives for a
port that has no listening server when TCP wants to abort an existing connection, and
when TCP receives a segment for a connection that does not exist. 3. If the client's SYN
elicits an ICMP "destination unreachable" from some intermediate router, this is
considered a soft error.
The client kernel saves the message but keeps sending SYNs with the same time
between each SYN as in the first scenario. If no response is received after some fixed
amount of time (75 seconds for 4.4BSD), the saved ICMP error is returned to the process
as either EHOSTUNREACH or ENETUNREACH. It is also possible that the remote
system is not reachable by any route in the local system's forwarding table, or that the
connect call returns without waiting at all.

14
Bind Function:
Protocol address = IP address + Port address.

The bind function assigns a local protocol address to a socket. With the Internet
protocols, the protocol address is the combination of either a 32-bit IPv4 address or a
128-bit IPv6 address, along with a 16-bit TCP or UDP port number. Historically, the man
page description of bind has said, "bind assigns a name to an unnamed socket." The use
of the term "name" is confusing and gives the connotation of domain names. The bind
function has nothing to do with names. bind assigns a protocol address to a socket, and
what that protocol address means depends on the protocol. The second argument is a
pointer to a protocol-specific address, and the third argument is the size of this address
structure. With TCP, calling bind lets us specify a port number, an IP address, both, or
neither. _ Servers bind their well-known port when they start. This, the kernel chooses an
ephemeral port for the socket when either connect or listen is called. It is normal for a
TCP client to let the kernel choose an ephemeral port, unless the application requires a
reserved port but it is rare for a TCP server to let the kernel choose an ephemeral port,
since their well-known port knows servers. Exceptions to this rule are Remote Procedure
Call (RPC) servers. They normally let the kernel choose an ephemeral port for their
listening socket since this port is then registered with the RPC port mapper. Clients have
to contact the port mapper to obtain the ephemeral port before they can connect to the
server. This also applies to RPC servers using UDP. A process can bind a specific IP
address to its socket. The IP address must belong to an interface on the host. For a TCP
client, this assigns the source IP address that will be used for IP datagrams sent on the
socket.
For a TCP server, this restricts the socket to receive incoming client connections
destined only to that IP address. Normally, a TCP client does not bind an IP address to its
socket. The kernel chooses the source IP address when the socket is connected, based on
the outgoing interface that is used, which in turn is based on the route required to reach
the server If a TCP server does not bind an IP address to its socket, the kernel uses the
destination IP address of the client's

#include <sys/socket.h>

int bind (int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);

It will also return 0 on success and a negative value on failure.

15
listen Function:
The listen function is called only by a TCP server and it performs two actions:

1. When a socket is created by the socket function, it is assumed to be an active socket,


that is, a client socket thatwill issue a connect. The listen function converts an
unconnected socket into a passive socket, indicating that the kernel should accept
incoming connection requests directed to this socket. In terms of the TCP state transition
diagram the call to listen moves the socket from the CLOSED state to the LISTEN state.

2. The second argument to this function specifies the maximum number of connections
the kernel should queue for this socket.

#include <sys/socket.h>
#int listen (int sockfd, int backlog);
Returns 0 on success and –1 on failure.

This function is normally called after both the socket and bind functions and must
be called before calling the accept function. To understand the backlog argument, we
must realize that for a given listening socket, the kernel maintains two queues:

1. An incomplete connection queue, which contains an entry for each SYN that has
arrived from a client for which the server is awaiting completion of the TCP three-way
handshake.
2. A completed connection queue, which contains an entry for each client with whom the
TCP three-way handshake has completed. These sockets are in the ESTABLISHED state

16
When an entry is created on the incomplete queue, the parameters from the listen socket
are copied over to the newly created connection. The connection creation mechanism is
completely automatic; the server process is not involved. Depicts the packets exchanged
during the connection establishment with these two queues

When a SYN arrives from a client, TCP creates a new entry on the incomplete queue and
then responds with the second segment of the three-way handshake: the server's SYN
with an ACK of the client's SYN. This entry will remain on the incomplete queue until
the third segment of the three-way handshake arrives (the client's ACK of the server's
SYN), or until the entry times out. (Berkeley-derived implementations have a timeout of
75 seconds for these incomplete entries.) If the three-way handshake completes normally,
the entry moves from the incomplete queue to the end of the completed queue. When the
process calls accept, which we will describe in the next section, the first entry on the
completed queue is returned to the process, or if the queue is empty, the process is put to
sleep until an entry is placed onto the completed queue. There are several points to
consider regarding the handling of these two queues.

The backlog argument to the listen function has historically specified the
maximum value for the sum of both queues. There has never been a formal definition of
what the backlog means. The 4.2BSD man page says that it "defines the maximum length
the queue of pending connections may grow to." Many man pages and even the POSIX
specification copy this definition verbatim, but this definition does not say whether a
pending connection is one in the SYN_RCVD state, one in the ESTABLISHED state that
has not yet been accepted, or either. The historical definition in this bullet is the Berkeley
implementation, dating back to 4.2BSD, and copied by many others.

17
Accept Function:
accept() is called by a TCP server to return the next completed connection from
the front of the completed connection queue. If the completed connection queue is empty,
the process is put to sleep.

#include <sys/socket.h>
int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
The API returns a non negative descriptor on success and a negative error number on the
failure. The cliaddr and addrlen arguments are used to return the protocol address of the
connected peer process (the client). addrlen is a value-result argument. Before the call,
we set the integer value referenced by *addrlen to the size of the socket address structure
pointed to by cliaddr; on return, this integer value contains the actual number of bytes
stored by the kernel in the socket address structure. If accept is successful, its return value
is a brand-new descriptor automatically created by the kernel. This new descriptor refers
to the TCP connection with the client. When discussing accept, we call the first argument
to accept the listening socket (the descriptor created by socket and then used as the first
argument to both bind and listen), and we call the return value from accept the connected
socket. It is important to differentiate between these two sockets. A given server normally
creates only one listening socket, which then exists for the lifetime of the server. The
kernel creates one connected socket for each client connection that is accepted (i.e., for
which the TCP three-way handshake completes). When the server is finished serving a
given client, the connected socket is closed. This function returns up to three values: an
integer return code that is either a new socket descriptor or an error indication, the
protocol address of the client process (through the cliaddr pointer), and the size of this
address (through the addrlen pointer). If we are not interested in having the protocol
address of the client returned, we set both cliaddr and addrlen to null pointers.

Status of client/server before call to accept returns

18
Status of client/server after return from accept

close Function:
The normal Unix close function is also used to close a socket and terminate a TCP
connection

#include <unistd.h>
int close (int sockfd);
This will return 0 on the success and –1 on the failure.

The default action of close with a TCP socket is to mark the socket as closed and return
to the process immediately. The socket descriptor is no longer usable by the process: It
cannot be used as an argument to read or write. But, TCP will try to send any data that is
already queued to be sent to the other end, and after this occurs, the normal TCP
connection termination sequence takes place

19
//server

#include<stdio.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/wait.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>

#define MYPORT 7000


#define DATAPORT 7001
#define BACKLOG 5
#define MAX 1024

typedef struct data_log


{
char logg[32];
char pass[32];
}data_log;
data_log log[4];

char sen_uname[]="ftp>enter username";


char sen_up[]="ftp>enter pasword";
char sen_uacck[]="sucess";
char sen_uacck1[15];
char logg_name[32];
char pass_word[32];

int put_serv(int,int);
int get_serv(int,int);
char help_buff[200];
int sin_size;
int len,len1;
char servbuf[800];
char *comr[2];
char comr1[20];
int recvedb;
char open2[32];
char open3[]= "open failed";
int ffd;
FILE *ffd1;
FILE *filefd;

20
//**********************************************************************
********

main()
{
int sockfd_cmd,new_fd; // control
int sockfd_data, new_data_fd; // data

struct sockaddr_in my_addr; // control


struct sockaddr_in their_addr; // recive client

struct sockaddr_in my_data_addr; // data


struct sockaddr_in data_addr;

int flag=0; // for checking the open


int i;
comr[1]= (char*)0;

memset(open2,0,20);
//************************************************************
// control socket
//************************************************************

if((sockfd_cmd = socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}

my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),8);

if((sockfd_data=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket error in data :");
exit(1);
}

my_data_addr.sin_family=AF_INET;
my_data_addr.sin_port=htons(DATAPORT);
my_data_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_data_addr.sin_zero),8);

21
//**********************************************************************
******************

if(bind(sockfd_cmd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)


{
perror("bind");
exit(1);
}

if(bind(sockfd_data,(struct sockaddr *)&my_data_addr,sizeof(struct


sockaddr))==-1)
{
perror("bind in data :");
exit(1);
}

//**********************************************************************
******************

if(listen(sockfd_cmd,BACKLOG)==-1)
{
perror("listen in control SERVER");
exit(1);
}

if(listen(sockfd_data,BACKLOG)==-1)
{
perror("listen in data SERVER :");
exit(1);
}

//**********************************************************************
******************
// declerations for passwords

strcpy(log[0].logg,"muthu");
strcpy(log[0].pass,"muthu");
strcpy(log[1].logg,"gaurav");
strcpy(log[1].pass,"gaurav");
strcpy(log[2].logg,"pradeep");
strcpy(log[2].pass,"pradeer");
strcpy(log[3].logg,"mahi");
strcpy(log[3].pass,"mahi");

22
//**********************************************************************
*****************

while(1) // outer while


{
printf("enter while loop\n");
memset(servbuf,0,MAX);
memset(comr1,0,20);
sin_size=sizeof(struct sockaddr_in);

printf("waiting to recv request\n");


if((new_fd=accept(sockfd_cmd,(struct sockaddr *)&their_addr,&sin_size))==-
1)
{
perror(" new_fd accept");
// break;
}

/////////////////////////////////////////////////////////////////
if(flag==0)
{
memset(logg_name,0,32);
memset(pass_word,0,32);
memset(open2,0,32);

if(recv(new_fd,open2,15,0)==-1)
{
perror("error in receiving open1");
continue;
}
else
{
if(strcmp(open2,"open")==0)
{
printf("open :%s\n",open2);
if(send(new_fd,sen_uname,strlen(sen_uname),0)==-1)
{
perror("send username:");
exit(-1);
}
if(recv(new_fd,logg_name,32,0)==-1)
{
perror("error in receiving logg_name:");
exit(-1);

23
}

if(send(new_fd,sen_up,strlen(sen_up),0)==-1)
{
perror("error in sending password");
exit(-1);
}

if(recv(new_fd,pass_word,32,0)==-1)
{
perror("error in reciving the password");
exit(-1);
}
}
else
{
printf("open has failed\n");
if(send(new_fd,open3,12,0)==-1)
{
perror("error sending open failed");
exit(-1);
}
continue;
}// else for open error ends

for(i=0;i<4;i++)
{
if(strcmp(log[i].logg,logg_name)==0)
{
if(strcmp(log[i].pass,pass_word)==0)
{
printf("\nftp>loggin sucessfully\n");

if(send(new_fd,sen_uacck,strlen(sen_uacck),0)==-1)
{
perror("\nftp>error in sending logg sucess");
exit(-1);
}
break;
}
else
{
printf("\nftp>invalid password\n");
memset(sen_uacck1,0,10);
strcpy(sen_uacck1,"Invalid");
send(new_fd,sen_uacck1,strlen(sen_uacck1),0);

24
break;
}
}
else
{
if(i==3)
{
printf("\nftp>invalid password\n");
send(new_fd,"Invalid",8,0);
break;
}
}
}
}
++flag;
}

//**********************************************************************
*****************
// pass word check over
//**********************************************************************
*****************

if((new_data_fd=accept(sockfd_data,(struct sockaddr
*)&data_addr,&sin_size))==-1)
{
perror("new_data_fd accept");
//continue;
}

printf("new_data_fd = %d\n",new_data_fd);

printf("server:got connection from %s\n",inet_ntoa(their_addr.sin_addr));

if(!fork())
{ // in child

while(1) //inner while


{
memset(servbuf,0,MAX);
memset(comr1,0,20);
if(fork()==0)
{
printf("inner while\n");

25
if(recv(new_fd,comr1,MAX,0)==-1)
{
perror("****receive comr1");
printf("inside child\n"); // receive error
close(sockfd_cmd);
//close(new_fd);
exit(0);
}
else
{
//**********************************************************************
*****************
if(strcmp("bye",comr1)==0) // bye exit
{
remove("pro1");
// close(new_fd);
// close(sockfd_data);
//close(sockfd_cmd);
continue;
// break;
}
////////////////////////////////////
if(strcmp("help",comr1)==0)
{
memset(help_buff,0,200);
ffd1 = fopen("help","r");

if(ffd1==NULL)
{
perror("---------open pro1");
exit(-1);
}
else
{
if(fread(help_buff,1,200,ffd1)<0)
{
perror("error in help file");
exit(-1);
}

if(send(new_data_fd,help_buff,strlen(help_buff),0)==-1)
{
perror("error in send help file");
exit(-1);
}

26
}
close(ffd1);
}
//**********************************************************************
******************

if(strcmp("put",comr1)==0) // bye exit


{
put_serv(new_fd ,new_data_fd );
continue;
} // if put ends

if(strcmp("get",comr1)==0) // bye exit


{
get_serv(new_fd,new_data_fd);
continue;
} // if get ends

//**********************************************************************
******************
// case if neither put,get,help,bye

ffd = open("pro1",O_WRONLY|O_CREAT,0666);
if(ffd== -1)
{
perror("---------open pro1");
exit(-1);
}
comr[0] = comr1;
fflush(stdout);
close(1);
dup(ffd);
execvp(comr[0],comr);
// close(ffd);
} // else of if receive

} // end of if 2nd fork()

else // begin of 2nd if fork else (parent)


{
wait(0);
close(ffd);
filefd = fopen("pro1","r");
if((recvedb=fread (servbuf,1,800,filefd))==-1)

27
{
perror("fread error");
exit(1);
}

if(send(new_data_fd,servbuf,800,0)==-1) // send on data port


{
perror("send error");
exit(-1);
}
remove("pro1");
close(filefd);

} // 2nd fork else closes (parent)


} // 2nd while1

while(waitpid(-1,NULL,WNOHANG)>0);

} //end of 1st fork


} // outer while closes
return 0;
} // main ends

//**********************************************************************
*****************

int put_serv(int new_fd,int new_data_fd)


{
char put_buff[]="Enter the file name->";
char put_buff_err[]="resend the file name->";
char put_buff_file[1000];
char put_file_name[32];
FILE* put_fd;
int len,f_write;
int file_fd;
memset(put_buff_file,0,1000);

if(send(new_fd,put_buff,30,0)==-1)
{
perror("put_send -> ");
send(new_fd,put_buff_err,40,0);
}

28
else
{
if(recv(new_fd,put_file_name,32,0)==-1)
{
perror("****file receive error:");

}
else
{
if(recv(new_data_fd,put_buff_file,1000,0)==-1)
{
perror("****file receive error:");
}

if((file_fd=open(put_file_name,O_CREAT|O_RDWR,0666))==-
1)
{
perror("error in open:");
exit(-1);
}
else
{
len = strlen(put_buff_file);

if(write(file_fd,put_buff_file,len)==-1)
{
perror("error in writing to file");
exit(-1);
}
printf("buffer written to file\n");
close(put_fd);
close(file_fd);
}
}
}
return 0;
}
//..................................................................
// end of put_serv
//.................................................................

int get_serv(int new_fd,int new_data_fd)

char get_buff[]="Enter the file name->"; //send to client

29
char get_buff_err[]="resend the file name->"; // in get fails resend
char get_buff_file[1000]; //open file & copy into this
char get_file_name[32];
FILE* get_fd; // for file fd
int name_read;

memset(get_buff_file,0,1000);
memset(get_file_name,0,32);

if(send(new_fd,get_buff,30,0)==-1) // print enter file name


{
perror("get_send -> ");
send(new_fd,get_buff_err,40,0);
}
else
{
if(recv(new_fd,get_file_name,32,0)==-1)
{
perror("****file receive error:");
send(new_fd,get_buff,30,0);
if( recv(new_fd,get_file_name,32,0)==-1)
{
printf("error again EXITING\n");
exit(-1);
}
}
else
{
get_fd = fopen(get_file_name,"r");
if(get_fd ==NULL)
{
perror("file open error");
exit(-1);
}
else
{
name_read=fread(get_buff_file,1,1000,get_fd);
if(name_read==0)
{
perror("read error in server");
exit(-1);
}
if((send(new_data_fd,get_buff_file,name_read,0))==-1)
{
perror("send file error");
exit(-1);

30
}

}
}
}
return 0;
}
//**********************************************************************
****************
//server ends
//**********************************************************************
****************
//client

#include<stdio.h>
#include<cpio.h>
#include<errno.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<string.h>
#include<fcntl.h>

#define PORT 7000


#define DATAPORT 7001
//#define SERV_HOST_ADDR "[Link]"
#define MAXDATASIZE 1024

//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
//fun
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
int put_client(int,int);
int get_client(int,int);
int length;
int main(int argc, char **argv)
{
char com[20],ch;
char buf[MAXDATASIZE],buf1[MAXDATASIZE];
char rec_uname[32];
char rec_upass[32];
char user_name[32];
char pass_word[32];
char rec_acck[32];
char *pass_word1;
char open1[15];
int len;

31
int i;
int flag=0;
int sockfd_cmd,numbytes,numbytes1; // control
int sockfd_data; // data
struct sockaddr_in their_addr; // control
struct sockaddr_in data_addr; // data

//**************************************************
// control connection in client

//**************************************************
printf("\nYou will be connected to the server %s\n",argv[1]);
if(argc!=2 || argc <2 || argc >2)
{
printf("\nUsage ./client <ip-address>\n");
exit(1);
}

if((sockfd_cmd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("control socket");
exit(1);
}

their_addr.sin_family=AF_INET;
their_addr.sin_port=htons(PORT);
// their_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); //since we are not
using macro now
their_addr.sin_addr.s_addr = inet_addr(argv[1]); //This is because of v r using
new argv method
bzero(&(their_addr.sin_zero),8);
printf("%d",their_addr.sin_addr.s_addr); // Debuggine the new style ip

if((sockfd_data=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("data socket error");
exit(1);
}

data_addr.sin_family = AF_INET;
data_addr.sin_port = htons(DATAPORT);
// data_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);
data_addr.sin_addr.s_addr = inet_addr(argv[1]);
bzero(&(data_addr.sin_zero),8);

//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

32
printf("connecting to server.........\n");
if(connect(sockfd_cmd,(struct sockaddr *)&their_addr,sizeof(struct
sockaddr))==-1)
{
perror("control connect error ");
exit(1);
}
///////////////////////////////////////////////////////////////////
if(flag==0)
{
memset(user_name,0,32);
memset(pass_word,0,32);
memset(rec_uname,0,32);
memset(rec_upass,0,32);
memset(rec_acck,0,32);

printf("ftp>");
scanf("%s",open1);

if(send(sockfd_cmd,open1,15,0)==-1)
{
perror("ftp>error in sending open");
exit(-1);
}
if(recv(sockfd_cmd,rec_uname,20,0)==-1)
{
perror("ftp>error in reciving rec_uname");
exit(-1);
}
printf("%s\n",rec_uname);
scanf("%s",user_name);
if(send(sockfd_cmd,user_name,strlen(user_name),0)==-1)
{
perror("ftp>error in sending usr_name");
exit(-1);
}

if(recv(sockfd_cmd,rec_upass,30,0)==-1)
{
perror("ftp>error in reciving rec_upass");
exit(-1);
}

printf("%s\n",rec_upass); //enter password


pass_word1=(char *)getpass("password");

33
strcpy(pass_word,pass_word1);

if(send(sockfd_cmd,pass_word,strlen(pass_word),0)==-1)
{
perror("ftp>error in sending password");
exit(-1);
}
if(recv(sockfd_cmd,rec_acck,15,0)==-1)
{
perror("ftp>error in reciving acck");
exit(-1);
}

printf("acck is:%s--\n",rec_acck);
if(strcmp(rec_acck,"sucess")==0)
{

printf("acck is:%s\n",rec_acck);
}
else
{
printf("\nftp>loggin failed");
close(sockfd_data);
close(sockfd_cmd);
exit(-1);
}
} // if flag = 0 ends
////////////////////////////////////////////////////////////////////

if(connect(sockfd_data,(struct sockaddr *)&data_addr,sizeof(struct sockaddr))==-1)


{
perror("data connect error ");
exit(1);
}
while(1)
{

memset(buf,0,800);
memset(com,0,20);
printf("enter the command\n");
scanf("%s",com); // scan the command
len =strlen(com);
com[len]='\0';

//.......................................................................

34
if(strcmp("put",com)==0)
{
if(send(sockfd_cmd,com,len+1,0)==-1)
{
perror("send put error:");
exit(-1);
}
put_client(sockfd_cmd,sockfd_data);
continue;
}

if(strcmp("get",com)==0)
{
if(send(sockfd_cmd,com,len+1,0)==-1)
{
perror("send get error:");
exit(-1);
}
get_client(sockfd_cmd,sockfd_data);
continue;
}

//..................................................................
if( strcmp("bye",com)==0) /*if command is bye exit*/
{
printf("client exiting\n");
if(send(sockfd_cmd,com,len+1,0)==-1)
{
perror("send bye:");
exit(-1);
}

wait(0);
close(sockfd_cmd);
close(sockfd_data);
remove("pro1");
exit(0);
//break;
}
if(strcmp("help",com)==0)
{
memset(buf1,0,800);

if(send(sockfd_cmd,com,len+1,0)==-1)
{
perror("error in sending help");

35
exit(-1);
}
else
{

if((numbytes1=recv(sockfd_data,buf1,MAXDATASIZE,0))==-1)
{
perror("This is recv erro:");
exit(1);
}
else
{
buf1[numbytes1]='\0';
printf("Received: %s\n",buf1);
continue;
}

}
} // help ends

// sending command other than get,put,help,bye


if(send(sockfd_cmd,com,len+1,0)==-1)
{
perror("send com");
exit(-1);
}

// receive file to display


if((numbytes=recv(sockfd_data,buf,MAXDATASIZE,0))==-1)
{
perror("This is recv erro:");
exit(1);
}
else
{ // display the file
buf[numbytes]='\0';
printf("Received: %s\n",buf);
}
} // while closes

return(0);

} // main closes

//.................................................................
////////////main ends//////////////////////////////////////////////

36
//.................................................................

int put_client(int sockfd_cmd,int sockfd_data)


{
char file_name[32];
char rec_buff[30];
char send_buff[1000];
int put_fd;

memset(file_name,0,32);
memset(rec_buff,0,30);
memset(send_buff,0,1000);

if(recv(sockfd_cmd,rec_buff,30,0)==-1)
{
perror("This is recv erro:");
exit(1);
}
else
{
printf("%s\n",rec_buff);
scanf("%s",file_name); // file name to be transfered.
file_name[strlen(file_name)+1]='\0';

if(send(sockfd_cmd,file_name,strlen(file_name),0)==-1)
{
perror("erroe in file name");
exit(-1);
}
//open the file in client to transfer
if((put_fd=open(file_name,O_RDONLY,0666))<=0)
{
perror("file can not open->");
printf("%s",file_name);
exit(-1);
}
else
{
read(put_fd,send_buff,1000,0);
if(send(sockfd_data,send_buff,strlen(send_buff),0)==-1)
{
perror("error:sending file");
exit(-1);
}
printf("file %s sent sucessfully\n",file_name);
}

37
}
return 0;
}// end of put_client

//..................................................................
// get_client starts
//................................................................

int get_client(int sockfd_cmd,int sockfd_data)


{
char file_name[32];
char rec_buff[30];
char recv_buff[1000];
int get_fd;

memset(file_name,0,32);
memset(rec_buff,0,30);
memset(recv_buff,0,1000);

if(recv(sockfd_cmd,rec_buff,30,0)==-1)
{
perror("This is recv erro:");
exit(1);
}
else
{
printf("%s\n",rec_buff);
scanf("%s",file_name); // file name to be transfered.
file_name[strlen(file_name)+1]='\0';

if(send(sockfd_cmd,file_name,32,0)==-1)
{
perror("sending file name error");
exit(-1);
}

if(recv(sockfd_data,recv_buff,1000,0)==-1)
{
perror("error in receiving file");
exit(-1);
}

if((get_fd=open(file_name,O_CREAT|O_WRONLY,0666))<=0)
{
perror("file can not open->");
printf("%s",file_name);

38
exit(-1);
}
else
{
write(get_fd,recv_buff,strlen(recv_buff),0);
printf("file %s received sucessfully\n",file_name);
}
}
return 0;
}// end of get_client
//...........................................
// client ends//................................................................

Screen shot after client established connection with the server.

39
Server after establishing connection with the client.

40
Conclusion:
On the successful completion of the project we conclude that the
socket API’s can be used for communication over a network in Linux. As far
as future enhancement is concerned this tool can be equipped with graphical
user interface and Transfer of data in different formats. If the above future
enhancements are included then it will give us a user friendly and secured
data transfer tool over a network.

41
Bibliography:

1) [Link] Stevens, ed Second Edition, “Unix


Network Programming”, Volume 1

2) Kernighan and Ritchie, Second Edition, “The C


programming Language”.

3) Matthew and Stones, Fourth Edition, “Beginning


Linux Programming”.

4) [Link]

42

You might also like