Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

ip.c

Go to the documentation of this file.
00001 /*
00002  * ip.c
00003  *
00004  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
00005  *
00006  * $Id: ip.c,v 1.29 2005/01/25 21:30:40 dugsong Exp $
00007  */
00008 
00009 #include "config.h"
00010 
00011 #include <netinet/in.h>
00012 
00013 #include <errno.h>
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include <unistd.h>
00018 
00019 #include "dnet.h"
00020 
00021 struct ip_handle {
00022         int     fd;
00023 };
00024 
00025 ip_t *
00026 ip_open(void)
00027 {
00028         ip_t *i;
00029         int n, len;
00030 
00031         if ((i = calloc(1, sizeof(*i))) == NULL)
00032                 return (NULL);
00033 
00034         if ((i->fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
00035                 return (ip_close(i));
00036 #ifdef IP_HDRINCL
00037         n = 1;
00038         if (setsockopt(i->fd, IPPROTO_IP, IP_HDRINCL, &n, sizeof(n)) < 0)
00039                 return (ip_close(i));
00040 #endif
00041 #ifdef SO_SNDBUF
00042         len = sizeof(n);
00043         if (getsockopt(i->fd, SOL_SOCKET, SO_SNDBUF, &n, &len) < 0)
00044                 return (ip_close(i));
00045 
00046         for (n += 128; n < 1048576; n += 128) {
00047                 if (setsockopt(i->fd, SOL_SOCKET, SO_SNDBUF, &n, len) < 0) {
00048                         if (errno == ENOBUFS)
00049                                 break;
00050                         return (ip_close(i));
00051                 }
00052         }
00053 #endif
00054 #ifdef SO_BROADCAST
00055         n = 1;
00056         if (setsockopt(i->fd, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n)) < 0)
00057                 return (ip_close(i));
00058 #endif
00059         return (i);
00060 }
00061 
00062 ssize_t
00063 ip_send(ip_t *i, const void *buf, size_t len)
00064 {
00065         struct ip_hdr *ip;
00066         struct sockaddr_in sin;
00067 
00068         ip = (struct ip_hdr *)buf;
00069 
00070         memset(&sin, 0, sizeof(sin));
00071 #ifdef HAVE_SOCKADDR_SA_LEN       
00072         sin.sin_len = sizeof(sin);
00073 #endif
00074         sin.sin_family = AF_INET;
00075         sin.sin_addr.s_addr = ip->ip_dst;
00076         
00077 #ifdef HAVE_RAWIP_HOST_OFFLEN
00078         ip->ip_len = ntohs(ip->ip_len);
00079         ip->ip_off = ntohs(ip->ip_off);
00080 
00081         len = sendto(i->fd, buf, len, 0,
00082             (struct sockaddr *)&sin, sizeof(sin));
00083         
00084         ip->ip_len = htons(ip->ip_len);
00085         ip->ip_off = htons(ip->ip_off);
00086 
00087         return (len);
00088 #else
00089         return (sendto(i->fd, buf, len, 0,
00090             (struct sockaddr *)&sin, sizeof(sin)));
00091 #endif
00092 }
00093 
00094 ip_t *
00095 ip_close(ip_t *i)
00096 {
00097         if (i != NULL) {
00098                 if (i->fd >= 0)
00099                         close(i->fd);
00100                 free(i);
00101         }
00102         return (NULL);
00103 }

Generated on Sun May 14 14:51:12 2006 by  doxygen 1.4.2