6 #include <sys/socket.h>
8 #include "greprotocol.h"
13 uint8_t reserved0_hi : 4;
17 uint8_t has_checksum : 1;
20 uint8_t reserved0_lo: 5;
22 uint16_t protocol_type;
26 GREProtocol::GREProtocol(const in6_addr &src, const in6_addr &dst)
28 memset(&dstaddr, 0, sizeof(dstaddr));
29 dstaddr.sin6_family = AF_INET6;
30 dstaddr.sin6_addr = dst;
32 sock = socket(AF_INET6, SOCK_RAW, IPPROTO_GRE);
39 memset(&my_addr, 0, sizeof(my_addr));
40 my_addr.sin6_family = AF_INET6;
41 my_addr.sin6_addr = src;
42 if (::bind(sock, (sockaddr *)&my_addr, sizeof(my_addr)) == -1) {
47 int buf = 10 << 20; // 20 MB.
48 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &buf, sizeof(buf)) == -1) {
49 perror("setsockopt(SO_RCVBUF)");
54 void GREProtocol::send_packet(uint16_t proto, const string &data, uint32_t incoming_seq)
57 gre_header *gre = (gre_header *)buf;
59 memset(gre, 0, sizeof(*gre));
62 gre->protocol_type = htons(proto);
64 char *ptr = buf + sizeof(*gre);
65 uint32_t seq_be = htonl(incoming_seq);
66 memcpy(ptr, &seq_be, sizeof(seq_be));
67 ptr += sizeof(seq_be);
69 memcpy(ptr, data.data(), data.size());
71 if (sendto(sock, buf, data.size() + sizeof(seq_be) + sizeof(*gre), 0, (sockaddr *)&dstaddr, sizeof(dstaddr)) == -1) {
79 int GREProtocol::fd() const
84 void GREProtocol::read_packet(Sender *sender)
86 struct sockaddr_storage addr;
87 socklen_t addrlen = sizeof(addr);
89 int ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&addr, &addrlen);
94 if (addr.ss_family != AF_INET6) {
97 struct in6_addr *addr6 = &((struct sockaddr_in6 *)&addr)->sin6_addr;
98 if (memcmp(addr6, &dstaddr.sin6_addr, sizeof(*addr6)) != 0) {
102 gre_header* gre = (gre_header *)buf;
104 char* ptr = buf + sizeof(gre_header);
105 if (gre->has_checksum) {
113 seq = ntohl(*(uint32_t *)ptr);
117 //printf("gre packet: proto=%x\n", ntohs(gre->protocol_type));
120 sender->send_packet(ntohs(gre->protocol_type), string(ptr, buf + ret), seq);