Tom Soulanille / snet
Committer:
altasoul
Date:
Wed Mar 04 02:04:32 2015 +0000
Revision:
0:6df0a6ed91d4
Child:
1:9c211ac06a12
refactor into Snet

Who changed what in which revision?

UserRevisionLine numberNew contents of line
altasoul 0:6df0a6ed91d4 1 #include "flyer.h"
altasoul 0:6df0a6ed91d4 2 #include "snet.h"
altasoul 0:6df0a6ed91d4 3
altasoul 0:6df0a6ed91d4 4 extern blackboard_t bb;
altasoul 0:6df0a6ed91d4 5 #if 0
altasoul 0:6df0a6ed91d4 6 extern Ethernet eth;
altasoul 0:6df0a6ed91d4 7
altasoul 0:6df0a6ed91d4 8 //-- from inet.cpp
altasoul 0:6df0a6ed91d4 9 extern uint16_t ones_complement_sum(const uint8_t *buf, int len, int sum);
altasoul 0:6df0a6ed91d4 10 extern uint16_t ip_checksum_of(const uint8_t *buf, const int len);
altasoul 0:6df0a6ed91d4 11 extern void turn_ip_packet_around(uint8_t *buf);
altasoul 0:6df0a6ed91d4 12 #endif
altasoul 0:6df0a6ed91d4 13
altasoul 0:6df0a6ed91d4 14 //-- from radio.cpp
altasoul 0:6df0a6ed91d4 15 extern void send_packet_to_radio(uint8_t const *, int);
altasoul 0:6df0a6ed91d4 16
altasoul 0:6df0a6ed91d4 17 //-- from util.cpp
altasoul 0:6df0a6ed91d4 18 extern void print_hex(const uint8_t *p, int len);
altasoul 0:6df0a6ed91d4 19
altasoul 0:6df0a6ed91d4 20 void Snet::turn_udp_packet_around(uint8_t *buf) {
altasoul 0:6df0a6ed91d4 21 uint8_t dh, dl;
altasoul 0:6df0a6ed91d4 22 turn_ip_packet_around(buf);
altasoul 0:6df0a6ed91d4 23 dh = buf[UDP_DST_PORT_O];
altasoul 0:6df0a6ed91d4 24 dl = buf[UDP_DST_PORT_O+1];
altasoul 0:6df0a6ed91d4 25 buf[UDP_DST_PORT_O] = buf[UDP_SRC_PORT_O];
altasoul 0:6df0a6ed91d4 26 buf[UDP_DST_PORT_O+1] = buf[UDP_SRC_PORT_O+1];
altasoul 0:6df0a6ed91d4 27 buf[UDP_SRC_PORT_O] = dh;
altasoul 0:6df0a6ed91d4 28 buf[UDP_SRC_PORT_O+1] = dl;
altasoul 0:6df0a6ed91d4 29 }
altasoul 0:6df0a6ed91d4 30
altasoul 0:6df0a6ed91d4 31 // Send a UDP packet addressed as in buf, with specified payload
altasoul 0:6df0a6ed91d4 32 void Snet::send_udp_packet(uint8_t *buf, const uint8_t *payload, int payload_len) {
altasoul 0:6df0a6ed91d4 33 int ip_total_length = UDP_PAYLOAD_O - IP_HEADER_O + payload_len;
altasoul 0:6df0a6ed91d4 34 int udp_length = UDP_HEADER_LEN + payload_len;
altasoul 0:6df0a6ed91d4 35 buf[IP_TOTAL_LENGTH_O] = ip_total_length >> 8;
altasoul 0:6df0a6ed91d4 36 buf[IP_TOTAL_LENGTH_O+1] = ip_total_length;
altasoul 0:6df0a6ed91d4 37
altasoul 0:6df0a6ed91d4 38 buf[UDP_LENGTH_O] = udp_length >> 8;
altasoul 0:6df0a6ed91d4 39 buf[UDP_LENGTH_O+1] = udp_length;
altasoul 0:6df0a6ed91d4 40 #if 0
altasoul 0:6df0a6ed91d4 41 // RFC1768: "An all zero transmitted
altasoul 0:6df0a6ed91d4 42 // checksum value means that the transmitter generated no checksum (for
altasoul 0:6df0a6ed91d4 43 // debugging or for higher level protocols that don't care)."
altasoul 0:6df0a6ed91d4 44 buf[UDP_CHECKSUM_O] = buf[UDP_CHECKSUM_O+1] = 0;
altasoul 0:6df0a6ed91d4 45 #else
altasoul 0:6df0a6ed91d4 46 // find the udp checksum for a given enet packet presumed to be udp
altasoul 0:6df0a6ed91d4 47 // From rfc768:
altasoul 0:6df0a6ed91d4 48 // The pseudo header conceptually prefixed to the UDP header contains the
altasoul 0:6df0a6ed91d4 49 // source address, the destination address, the protocol, and the UDP
altasoul 0:6df0a6ed91d4 50 // length. This information gives protection against misrouted datagrams.
altasoul 0:6df0a6ed91d4 51 // This checksum procedure is the same as is used in TCP.
altasoul 0:6df0a6ed91d4 52 //
altasoul 0:6df0a6ed91d4 53 // 0 7 8 15 16 23 24 31
altasoul 0:6df0a6ed91d4 54 // +--------+--------+--------+--------+
altasoul 0:6df0a6ed91d4 55 // | source address |
altasoul 0:6df0a6ed91d4 56 // +--------+--------+--------+--------+
altasoul 0:6df0a6ed91d4 57 // | destination address |
altasoul 0:6df0a6ed91d4 58 // +--------+--------+--------+--------+
altasoul 0:6df0a6ed91d4 59 // | zero |protocol| UDP length |
altasoul 0:6df0a6ed91d4 60 // +--------+--------+--------+--------+
altasoul 0:6df0a6ed91d4 61 //
altasoul 0:6df0a6ed91d4 62 // If the computed checksum is zero, it is transmitted as all ones (the
altasoul 0:6df0a6ed91d4 63 // equivalent in one's complement arithmetic). An all zero transmitted
altasoul 0:6df0a6ed91d4 64 // checksum value means that the transmitter generated no checksum (for
altasoul 0:6df0a6ed91d4 65 // debugging or for higher level protocols that don't care).
altasoul 0:6df0a6ed91d4 66
altasoul 0:6df0a6ed91d4 67 // This is the pseudo-header sum
altasoul 0:6df0a6ed91d4 68 int sum = ones_complement_sum(&buf[IP_SADDR_O], 4+4, 0);
altasoul 0:6df0a6ed91d4 69 sum += 0x11; // proto
altasoul 0:6df0a6ed91d4 70 sum += 8 + payload_len; // UDP length
altasoul 0:6df0a6ed91d4 71
altasoul 0:6df0a6ed91d4 72 // add the real UDP header, with zeroed-out checksum
altasoul 0:6df0a6ed91d4 73 buf[UDP_CHECKSUM_O] = buf[UDP_CHECKSUM_O+1] = 0;
altasoul 0:6df0a6ed91d4 74 sum = ones_complement_sum(&buf[UDP_HEADER_O],
altasoul 0:6df0a6ed91d4 75 UDP_PAYLOAD_O - UDP_HEADER_O,
altasoul 0:6df0a6ed91d4 76 sum);
altasoul 0:6df0a6ed91d4 77
altasoul 0:6df0a6ed91d4 78 // add the payload that will be included and take the result
altasoul 0:6df0a6ed91d4 79 int chksum = ~ones_complement_sum(payload, payload_len, sum);
altasoul 0:6df0a6ed91d4 80
altasoul 0:6df0a6ed91d4 81 chksum = chksum ? chksum : ~chksum; // send -0 for +0
altasoul 0:6df0a6ed91d4 82 buf[UDP_CHECKSUM_O] = chksum >> 8;
altasoul 0:6df0a6ed91d4 83 buf[UDP_CHECKSUM_O+1] = chksum;
altasoul 0:6df0a6ed91d4 84 #endif
altasoul 0:6df0a6ed91d4 85 buf[IP_CHKSUM_O] = buf[IP_CHKSUM_O+1] = 0;
altasoul 0:6df0a6ed91d4 86 int chk = ip_checksum_of(&buf[IP_HEADER_O], IP_HEADER_LEN);
altasoul 0:6df0a6ed91d4 87 buf[IP_CHKSUM_O] = chk >> 8;
altasoul 0:6df0a6ed91d4 88 buf[IP_CHKSUM_O+1] = chk;
altasoul 0:6df0a6ed91d4 89 eth.write((char *) buf, UDP_PAYLOAD_O);
altasoul 0:6df0a6ed91d4 90 eth.write((char *) payload, payload_len);
altasoul 0:6df0a6ed91d4 91 eth.send();
altasoul 0:6df0a6ed91d4 92 #if 0
altasoul 0:6df0a6ed91d4 93 printf("rup wrote:");
altasoul 0:6df0a6ed91d4 94 print_hex(buf, UDP_PAYLOAD_O);
altasoul 0:6df0a6ed91d4 95 printf("then wrote:");
altasoul 0:6df0a6ed91d4 96 print_hex((uint8_t *) payload, payload_len);
altasoul 0:6df0a6ed91d4 97 printf("udp chksum 0x%02x%02x\r\n", buf[UDP_CHECKSUM_O], buf[UDP_CHECKSUM_O+1]);
altasoul 0:6df0a6ed91d4 98 #endif
altasoul 0:6df0a6ed91d4 99 }
altasoul 0:6df0a6ed91d4 100
altasoul 0:6df0a6ed91d4 101 // Return a UDP packet to the sender of packet in buf, with new payload
altasoul 0:6df0a6ed91d4 102 void Snet::return_udp_packet(uint8_t *buf, const uint8_t *payload, int payload_len) {
altasoul 0:6df0a6ed91d4 103 turn_udp_packet_around(buf);
altasoul 0:6df0a6ed91d4 104 send_udp_packet(buf, payload, payload_len);
altasoul 0:6df0a6ed91d4 105 }
altasoul 0:6df0a6ed91d4 106
altasoul 0:6df0a6ed91d4 107
altasoul 0:6df0a6ed91d4 108
altasoul 0:6df0a6ed91d4 109 void Snet::send_to_correspondent(const uint8_t *what, int what_len) {
altasoul 0:6df0a6ed91d4 110 send_udp_packet(correspondent_facing_packet_header, what, what_len);
altasoul 0:6df0a6ed91d4 111 }
altasoul 0:6df0a6ed91d4 112
altasoul 0:6df0a6ed91d4 113 void Snet::tell_correspondent(char *s) {
altasoul 0:6df0a6ed91d4 114 send_to_correspondent((const uint8_t *) s, strlen(s));
altasoul 0:6df0a6ed91d4 115 }
altasoul 0:6df0a6ed91d4 116
altasoul 0:6df0a6ed91d4 117 void Snet::register_correspondent_for_updates(uint8_t *buf, int len, char updates) {
altasoul 0:6df0a6ed91d4 118 turn_udp_packet_around(buf);
altasoul 0:6df0a6ed91d4 119 memcpy(correspondent_facing_packet_header, buf, UDP_PAYLOAD_O);
altasoul 0:6df0a6ed91d4 120 bb.updates_for_which_registered = updates;
altasoul 0:6df0a6ed91d4 121 //printf("registered for updates: 0x%x\r\n", updates); //DEBUG
altasoul 0:6df0a6ed91d4 122 tell_correspondent("OK");
altasoul 0:6df0a6ed91d4 123 }
altasoul 0:6df0a6ed91d4 124
altasoul 0:6df0a6ed91d4 125 // Hint: $ sudo tcpdump -i eth0 -vvv -Ump -X udp port 2497
altasoul 0:6df0a6ed91d4 126 void Snet::handle_quaddb_packet(uint8_t *buf, int len) {
altasoul 0:6df0a6ed91d4 127 uint16_t payload_length
altasoul 0:6df0a6ed91d4 128 = (buf[UDP_LENGTH_O]<<8) + buf[UDP_LENGTH_O+1]
altasoul 0:6df0a6ed91d4 129 - (UDP_PAYLOAD_O - UDP_HEADER_O);
altasoul 0:6df0a6ed91d4 130 #if 0
altasoul 0:6df0a6ed91d4 131 printf("quaddb %d bytes:", payload_length);
altasoul 0:6df0a6ed91d4 132 print_hex(&buf[UDP_PAYLOAD_O], len-UDP_PAYLOAD_O);
altasoul 0:6df0a6ed91d4 133 #endif
altasoul 0:6df0a6ed91d4 134 char *payload = (char *) &buf[UDP_PAYLOAD_O];
altasoul 0:6df0a6ed91d4 135 switch (payload[0]) {
altasoul 0:6df0a6ed91d4 136 case '~':
altasoul 0:6df0a6ed91d4 137 send_packet_to_radio((uint8_t *)payload+1, payload_length-1);
altasoul 0:6df0a6ed91d4 138 break;
altasoul 0:6df0a6ed91d4 139 case '?':
altasoul 0:6df0a6ed91d4 140 if (strcmp(payload+1, "bb") == 0) {
altasoul 0:6df0a6ed91d4 141 // printf("got '?bb'\r\n"); //DEBUG
altasoul 0:6df0a6ed91d4 142 return_udp_packet(buf, (const uint8_t *) &bb, sizeof(bb));
altasoul 0:6df0a6ed91d4 143 };
altasoul 0:6df0a6ed91d4 144 break;
altasoul 0:6df0a6ed91d4 145 case 'e': //echo
altasoul 0:6df0a6ed91d4 146 //printf("echo %d bytes\r\n", payload_length-1); //DEBUG
altasoul 0:6df0a6ed91d4 147 return_udp_packet(buf, (const uint8_t *) payload+1, payload_length-1);
altasoul 0:6df0a6ed91d4 148 break;
altasoul 0:6df0a6ed91d4 149 case 'r': //register
altasoul 0:6df0a6ed91d4 150 register_correspondent_for_updates(buf, len, payload[1]);
altasoul 0:6df0a6ed91d4 151 break;
altasoul 0:6df0a6ed91d4 152 default:
altasoul 0:6df0a6ed91d4 153 printf("Unknown request:");
altasoul 0:6df0a6ed91d4 154 print_hex(&buf[UDP_PAYLOAD_O], payload_length);
altasoul 0:6df0a6ed91d4 155 }
altasoul 0:6df0a6ed91d4 156 };
altasoul 0:6df0a6ed91d4 157
altasoul 0:6df0a6ed91d4 158
altasoul 0:6df0a6ed91d4 159 void Snet::handle_udp_packet(uint8_t *buf, int len) {
altasoul 0:6df0a6ed91d4 160 #if 0
altasoul 0:6df0a6ed91d4 161 printf("UDP:");
altasoul 0:6df0a6ed91d4 162 print_hex(&buf[UDP_HEADER_O], len-UDP_HEADER_O);
altasoul 0:6df0a6ed91d4 163 #endif
altasoul 0:6df0a6ed91d4 164 // /etc/services has: quaddb 2497/udp # Quad DB
altasoul 0:6df0a6ed91d4 165 // It appears to be defunct. Cute, we'll take it.
altasoul 0:6df0a6ed91d4 166 if (buf[UDP_DST_PORT_O+0] == 0x09
altasoul 0:6df0a6ed91d4 167 && buf[UDP_DST_PORT_O+1] == 0xc1) {
altasoul 0:6df0a6ed91d4 168 handle_quaddb_packet(buf, len);
altasoul 0:6df0a6ed91d4 169 }
altasoul 0:6df0a6ed91d4 170 };