CSCI.4220 Network Programming
Class 10, Thursday February 24, 2005
More IPv6 and Miscellaneous socket stuff

email spoofing

Here is a run stream which uses telnet to connect directly to the CS Dept mail server and spoofs an email address.
telnet cliffclavin.cs.rpi.edu 25
Trying 128.213.1.9...
Connected to cliffclavin.cs.rpi.edu (128.213.1.9).
Escape character is '^]'.
220 cliffclavin.cs.rpi.edu ESMTP Sendmail 8.12.10/8.12.10; Thu, 24 Feb 2005 11:0
9:38 -0500 (EST)
HELO cs.rpi.edu
250 cliffclavin.cs.rpi.edu Hello ingallsr@mary-kate.cs.rpi.edu [128.213.7.4], 
pleased to meet you
MAIL FROM:
250 2.1.0 ... Sender ok
RCPT TO:
250 2.1.5 ... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Here is the message
.
250 2.0.0 j1OG9cuZ064912 Message accepted for delivery
QUIT
221 2.0.0 cliffclavin.cs.rpi.edu closing connection
Connection closed by foreign host.

IPv6 sockets

The function
struct hostent gethostbyname2(char *name, int family)
can be used to get an IPv6 address if the second arg is AF_INET6 The recommended method is to use getaddrinfo

  #include<netdb.h>

  int getaddrinfo(const char hostname, const char service,
                const struct addrinfo *hints, 
                struct addrinfo **result);

  struct addrinfo {
     int ai_flags;
     int ai_family; /* AF_INET, AF_INET6, AI_UNSPEC etc */  
     int ai_socktype; /* SOCK_STREAM, SOCK_DGRAM, etc /*
     int ai_protocol;  /* 0 or IPPROTO_xxx */
     socklen_t ai_addrlen;
     char *ai_canonname;  /* canonical name of server */
     struct sockaddr *ai_addr;
     struct addrinfo *ai_next; /* ptr to next struct 
                                  in linked list */
  };

  Service is either a service name or a 
  decimal port number string

  char *gai_strerror(int error) /* arg is return val 
                                   from getaddrinfo */

  void freeaddrinfo(struct addrinfo *ai); /* ai should be 
     linked list head (first struct returned) */
Here is code, more or less taken from the text, which uses this function to connect using either v4 or v6

/* connects to either a v4 or v6 server 
   from text page 327 */

int tcp_connect(const char *host, const char *serv)
{
    int sockfd, n;
    struct addrinfo hints, *res, *ressave;
 
    memset(&hints, 0, sizeof(struct addrinfo);  
                /* book uses bzero */
    hints.ai_family = AI_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    n = getaddrinfo(host, serv, &hints, &res);
    if (n != 0) 
       err_quit("tcp connect error for %s %s: %s,
                 host, serv, gai_strerror(n));
    ressave = res;

    do {
       sockfd = socket(res->ai_family, res->ai_socktype, 
                       res->ai_protocol);
       if (sockfd < 0) 
          continue;
       if (connect(sockfd, res->ai_addr, res->ai_addrlen)==0)
          break; /*success */
       Close(sockfd);
    }
    while (res = res->ai_next) != NULL);
    if (res == NULL) 
       err_sys("tcp_connect error for %s %s", host, serv);
    freeaddrinfo(ressave);
    return sockfd;
}

Unix domain protocols

Not an actual protocol suite, but a way of performing client/server communication on a single host.
struct sockaddr_un {
    sa_family_t sun_family;  /* AF_LOCAL or AF_UNIX */
    char sun_path[104];      /* null terminated pathname */
};

unixserver.c
unixclient.c

To use these, pass in a path name as the arg.

Using SIGALRM to interrupt a read or recv

udptimeo.c

Interrupt driven IO

This program demonstrates signal driven I/O on a socket. The program can be doing other stuff, and when a new connection arrives on the listening socket, the program is interrupted with a SIGIO signal, and so it stops what it is doing and handles the connection. All of the socket communication is done in the signal handler function.

sigioserver.c