00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "config.h"
00010
00011 #include <sys/types.h>
00012 #include <sys/ioctl.h>
00013 #include <sys/socket.h>
00014
00015 #include <net/if.h>
00016 #include <net/raw.h>
00017
00018 #include <assert.h>
00019 #include <errno.h>
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022
00023 #include "dnet.h"
00024
00025 struct eth_handle {
00026 int fd;
00027 struct ifreq ifr;
00028 };
00029
00030 eth_t *
00031 eth_open(const char *device)
00032 {
00033 struct sockaddr_raw sr;
00034 eth_t *e;
00035 int n;
00036
00037 if ((e = calloc(1, sizeof(*e))) == NULL)
00038 return (NULL);
00039
00040 if ((e->fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP)) < 0)
00041 return (eth_close(e));
00042
00043 memset(&sr, 0, sizeof(sr));
00044 sr.sr_family = AF_RAW;
00045 strlcpy(sr.sr_ifname, device, sizeof(sr.sr_ifname));
00046
00047 if (bind(e->fd, (struct sockaddr *)&sr, sizeof(sr)) < 0)
00048 return (eth_close(e));
00049
00050 n = 60000;
00051 if (setsockopt(e->fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)) < 0)
00052 return (eth_close(e));
00053
00054 strlcpy(e->ifr.ifr_name, device, sizeof(e->ifr.ifr_name));
00055
00056 return (e);
00057 }
00058
00059 int
00060 eth_get(eth_t *e, eth_addr_t *ea)
00061 {
00062 struct addr ha;
00063
00064 if (ioctl(e->fd, SIOCGIFADDR, &e->ifr) < 0)
00065 return (-1);
00066
00067 if (addr_ston(&e->ifr.ifr_addr, &ha) < 0)
00068 return (-1);
00069
00070 if (ha.addr_type != ADDR_TYPE_ETH) {
00071 errno = EINVAL;
00072 return (-1);
00073 }
00074 memcpy(ea, &ha.addr_eth, sizeof(*ea));
00075
00076 return (0);
00077 }
00078
00079 int
00080 eth_set(eth_t *e, const eth_addr_t *ea)
00081 {
00082 struct addr ha;
00083
00084 ha.addr_type = ADDR_TYPE_ETH;
00085 ha.addr_bits = ETH_ADDR_BITS;
00086 memcpy(&ha.addr_eth, ea, ETH_ADDR_LEN);
00087
00088 if (addr_ntos(&ha, &e->ifr.ifr_addr) < 0)
00089 return (-1);
00090
00091 return (ioctl(e->fd, SIOCSIFADDR, &e->ifr));
00092 }
00093
00094 ssize_t
00095 eth_send(eth_t *e, const void *buf, size_t len)
00096 {
00097 return (write(e->fd, buf, len));
00098 }
00099
00100 eth_t *
00101 eth_close(eth_t *e)
00102 {
00103 if (e != NULL) {
00104 if (e->fd >= 0)
00105 close(e->fd);
00106 free(e);
00107 }
00108 return (NULL);
00109 }