00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <stdarg.h>
00026 #include <stdint.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <sys/socket.h>
00030 #include <sys/param.h>
00031 #include <unistd.h>
00032 #include <sys/ioctl.h>
00033 #include <netinet/in.h>
00034 #include <net/if.h>
00035 #include <netdb.h>
00036 #include <arpa/inet.h>
00037
00038 #include <linux/if_ether.h>
00039
00040 #include "str.h"
00041 #include "net_udp.h"
00042 #include "arping.h"
00043
00044
00045 int32_t get_src_addr(struct param *p){
00046 struct ifreq ifr;
00047 struct sockaddr_in *sin;
00048 int fd;
00049 int reuse = 1;
00050
00051 fd = socket(AF_INET, SOCK_DGRAM, 0);
00052 if (fd < 0) {
00053 fprintf(stderr, "Socket error\n");
00054 return -1;
00055 }
00056
00057 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) != 0) {
00058 fprintf(stderr, "setsockopt error: SO_REUSEADDR\n");
00059 return -1;
00060 }
00061 #ifdef SO_REUSEPORT
00062 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse, sizeof(reuse)) != 0) {
00063 fprintf(stderr, "setsockopt error: SO_REUSEPORT\n");
00064 return -1;
00065 }
00066 #endif
00067
00068 memset(&ifr, 0, sizeof(ifr));
00069 strcpy(ifr.ifr_name, "eth0");
00070
00071 if(ioctl(fd, SIOCGIFADDR, &ifr) != 0){
00072 fprintf(stderr, "Local address resolution error\n");
00073 return -1;
00074 }
00075
00076 sin = (struct sockaddr_in*) (ifr.ifr_addr.sa_data+2);
00077 p->src_addr4 = *(struct in_addr*)sin;
00078 p->src = inet_ntoa(p->src_addr4);
00079
00080 close(fd);
00081
00082 return 0;
00083 }
00084
00085
00086 int32_t udp_init4(struct param *p)
00087 {
00088 int reuse = 1;
00089 struct ifreq ifr;
00090 struct sockaddr_in *sin;
00091 in_addr_t src_net, dst_net;
00092
00093
00094
00095 if(inet_pton(AF_INET, p->dst, &p->dst_addr4) != 1) {
00096 struct hostent *h = gethostbyname(p->dst);
00097 if(h == NULL) {
00098 fprintf(stderr, "Can't resolve IP address for %s\n", p->dst);
00099 return -1;
00100 }
00101 memcpy(&(p->dst_addr4), h->h_addr_list[0], sizeof(p->dst_addr4));
00102 }
00103
00104 if(!p->raw){
00105 p->fd = socket(AF_INET, SOCK_DGRAM, 0);
00106 if (p->fd < 0) {
00107 fprintf(stderr, "Socket error\n");
00108 return -1;
00109 }
00110 if (setsockopt(p->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse,
00111 sizeof(reuse)) != 0) {
00112 fprintf(stderr, "setsockopt error: SO_REUSEADDR\n");
00113 return -1;
00114 }
00115 #ifdef SO_REUSEPORT
00116 if (setsockopt(p->fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse,
00117 sizeof(reuse)) != 0) {
00118 fprintf(stderr, "setsockopt error: SO_REUSEPORT\n");
00119 return -1;
00120 }
00121 #endif
00122
00123 if(IN_MULTICAST(ntohl(p->dst_addr4.s_addr))) {
00124 struct ip_mreq imr;
00125
00126 imr.imr_multiaddr.s_addr = p->dst_addr4.s_addr;
00127 imr.imr_interface.s_addr = 0;
00128
00129 if(setsockopt(p->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq)) != 0) {
00130 fprintf(stderr, "setsockopt error: IP_ADD_MEMBERSHIP\n");
00131 return -1;
00132 }
00133 if(setsockopt(p->fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &p->ttl, sizeof(p->ttl)) != 0) {
00134 fprintf(stderr, "setsockopt error: IP_MULTICAST_TTL\n");
00135 return -1;
00136 }
00137 }
00138 } else {
00139 p->fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
00140 if(p->fd < 0) {
00141 fprintf(stderr, "Socket error\n");
00142 return -1;
00143 }
00144 }
00145
00146 memset(&ifr, 0, sizeof(ifr));
00147 strcpy(ifr.ifr_name, "eth0");
00148
00149 if(ioctl(p->fd, SIOCGIFADDR, &ifr) != 0){
00150 fprintf(stderr, "Local address resolution error\n");
00151 return -1;
00152 }
00153 sin = (struct sockaddr_in*) (ifr.ifr_addr.sa_data+2);
00154 p->src_addr4 = *(struct in_addr*)sin;
00155 p->src = inet_ntoa(p->src_addr4);
00156 p->eth_index = ifr.ifr_ifindex;
00157
00158 if(ioctl(p->fd, SIOCGIFNETMASK, &ifr) != 0){
00159 fprintf(stderr, "Local address netmask resolution error\n");
00160 return -1;
00161 }
00162 sin = (struct sockaddr_in*) (ifr.ifr_netmask.sa_data+2);
00163 p->src_netmask4 = *(struct in_addr*)sin;
00164
00165 if(ioctl(p->fd, SIOCGIFHWADDR, &ifr) != 0){
00166 fprintf(stderr, "MAC resolution error\n");
00167 return -1;
00168 }
00169 memcpy(p->mac, ifr.ifr_hwaddr.sa_data, 6);
00170
00171 if (!IN_MULTICAST(ntohl(p->dst_addr4.s_addr))) {
00172 uint32_t dstip;
00173 uint8_t mac[6];
00174
00175 src_net = p->src_netmask4.s_addr & p->src_addr4.s_addr;
00176 dst_net = p->src_netmask4.s_addr & p->dst_addr4.s_addr;
00177 if(src_net == dst_net){
00178 dstip = p->dst_addr4.s_addr;
00179 } else {
00180
00181 FILE *fp = fopen("/proc/net/route", "r");
00182 unsigned long int d, g, m;
00183 int flgs, ref, use, metric, mtu, win, ir;
00184 int fl=0;
00185 char devname[64];
00186 if (fscanf(fp, "%*[^\n]\n") < 0) {
00187
00188 fprintf(stderr, "Gateway resolution error\n");
00189 return -1;
00190 }
00191 while (1) {
00192 int r;
00193 r = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n",
00194 devname, &d, &g, &flgs, &ref, &use, &metric, &m,
00195 &mtu, &win, &ir);
00196 if (r != 11) {
00197 if ((r < 0) && feof(fp)) {
00198 break;
00199 }
00200 fprintf(stderr, "Gateway resolution error!\n");
00201 return -1;
00202 }
00203 if(!d){
00204 fl=1;
00205 break;
00206 }
00207 }
00208 if(!fl){
00209 fprintf(stderr, "Gateway resolution error\n");
00210 return -1;
00211 }
00212 dstip = g;
00213 }
00214 memset(mac, 0, 6);
00215
00216 if(arping(p->src_addr4, *((struct in_addr*) &dstip), mac) != 0){
00217 fprintf(stderr, "Destination address is not resolved\n");
00218 return -1;
00219 }
00220
00221 memcpy(p->dst_mac, mac, 6);
00222 }
00223
00224 return 0;
00225 }
00226
00227
00228 void udp_exit4(struct param * p)
00229 {
00230 if(!p->raw){
00231 if (IN_MULTICAST(ntohl(p->dst_addr4.s_addr))) {
00232 struct ip_mreq imr;
00233 imr.imr_multiaddr.s_addr = p->dst_addr4.s_addr;
00234 imr.imr_interface.s_addr = INADDR_ANY;
00235 if (setsockopt(p->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq)) != 0) {
00236 fprintf(stderr, "setsockopt IP_DROP_MEMBERSHIP\n");
00237 abort();
00238 }
00239 }
00240 }
00241 close(p->fd);
00242 }
00243