8 #include <sys/socket.h>
9 #include <netpacket/packet.h>
10 #include <net/ethernet.h>
11 #include <sys/ioctl.h>
13 #include <netinet/in.h>
18 int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
20 struct sockaddr_ll sll;
21 socklen_t sll_len = sizeof(sll);
23 //struct sockaddr_in sin;
24 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))
26 perror("setsockopt()");
29 memset(&ifr, 0, sizeof(ifr));
30 strncpy(ifr.ifr_name, "eth0", sizeof(ifr));
31 if (ioctl(s, SIOCGIFINDEX, &ifr) == -1)
36 memset(&sll, 0, sizeof(struct sockaddr_ll));
37 sll.sll_family = AF_PACKET;
39 sll.sll_ifindex = ifr.ifr_ifindex;
40 sll.sll_pkttype = PACKET_HOST; // nada de recibir broadcasts, etc.
43 if (bind(s, (struct sockaddr*)&sll, sizeof(sll)))
50 memset(&sin, 0, sizeof(sin));
51 sin.sin_family = AF_INET;
52 sin.sin_port = htons(2900);
53 sin.sin_addr.s_addr = INADDR_ANY;
54 if (bind(s, (struct sockaddr*)&sin, sizeof(sin)))
62 eth_addr_local[0] = 0x00;
63 eth_addr_local[1] = 0x0c;
64 eth_addr_local[2] = 0x6e;
65 eth_addr_local[3] = 0x37;
66 eth_addr_local[4] = 0x19;
67 eth_addr_local[5] = 0xbf;
69 ip_addr_local[0] = 0x0a;
70 ip_addr_local[1] = 0x0a;
71 ip_addr_local[2] = 0x0a;
72 ip_addr_local[3] = 0x02;
74 udp_port_local = WORD(0x0b, 0x54); // 2900
76 while (1) // escuchamos forever
81 printf("Recibiendo... "); fflush(stdout);
82 //if (recvfrom(s, net_buffer, sizeof(net_buffer), 0,
83 // (struct sockaddr*) &sll, &sll_len) < 0)
84 if (recv(s, net_buffer, sizeof(net_buffer), 0) < 0)
90 if (!eth_read_frame_header())
92 printf("Header ethernet inválido: DROP!\n");
97 printf("No le damos bola a ARP por ahora: DROP!\n");
100 if (!ip_read_packet_header())
102 printf("Header ip inválido: DROP!\n");
107 printf("No le damos bola a ICMP por ahora: DROP!\n");
110 if (!udp_read_dgram_header())
112 printf("Header udp inválido: DROP!\n");
116 for (i = 0; i < (udp_dgram_len - 8); ++i) // 8 == hdr udp
117 printf("0x%02X ", net_getb());
120 // Como hago echo, y el tamaño de las cabeceras no cambian,
121 // basta con sólo reescribir las cabeceras
122 eth_write_frame_header();
123 ip_write_packet_header();
124 udp_write_dgram_header();
127 // Setup para escribir header eth
128 eth_addr_remote[0] = 0x00;
129 eth_addr_remote[1] = 0xd0;
130 eth_addr_remote[2] = 0x09;
131 eth_addr_remote[3] = 0xac;
132 eth_addr_remote[4] = 0x32;
133 eth_addr_remote[5] = 0xe0;
135 // Escribo header eth
136 eth_write_frame_header();
137 // Setup para escribir header ip
138 ip_addr_remote[0] = 0x0a;
139 ip_addr_remote[1] = 0x0a;
140 ip_addr_remote[2] = 0x0a;
141 ip_addr_remote[3] = 0x01;
142 // TODO para setear el tamaño del paquete habría que poner solo el
143 // tamaño del payload de UDP y calcular el resto en base a eso.
144 ip_packet_len = 20 + 8 + 5; // ip + udp + "hola"
147 ip_write_packet_header();
148 // Setup para escribir header udp
149 udp_port_remote = WORD(0x0b, 0x54);
150 udp_dgram_len = 8 + 5; // udp + "hola"
151 // Escribo header udp
152 udp_write_dgram_header();
154 net_putb(0x68); net_putb(0x6f); net_putb(0x6c); net_putb(0x61);
157 // Trato de mandar...
158 printf("Mandando a %u.%u.%u.%u:%u (%02X:%02X:%02X:%02X:%02X:%02X)\n",
159 ip_addr_remote[0], ip_addr_remote[1], ip_addr_remote[2],
160 ip_addr_remote[3], udp_port_remote,
161 eth_addr_remote[0], eth_addr_remote[1], eth_addr_remote[2],
162 eth_addr_remote[3], eth_addr_remote[4], eth_addr_remote[5]);
163 i = 14 /* eth hdr */ + ip_packet_len;
164 if (i < 60) // tamaño mínimo de ethernet
166 if (send(s, net_buffer, i, 0) < 0)