├── Makefile ├── README ├── mactelnet.c ├── md5.c ├── md5.h ├── mndp.h └── protocol.h /Makefile: -------------------------------------------------------------------------------- 1 | all: mt 2 | 3 | clean: dist-clean 4 | 5 | dist-clean: 6 | rm -f mactelnet 7 | 8 | mt: 9 | gcc -Wall mactelnet.c md5.c -o mactelnet -I/usr/local/include/libnet11 -L/usr/local/lib/libnet11 -lnet -lpcap 10 | debug: 11 | gcc -Wall mactelnet.c md5.c -o mactelnet -I/usr/local/include/libnet11 -L/usr/local/lib/libnet11 -lnet -lpcap -D__DEBUG 12 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Required libraries 2 | ------------------------------------------------------------------------------- 3 | MAC-Telnet requires libpcap and libnet. Installation in Ubuntu GNU/Linux or 4 | any other Debian-based distribution is quite simple: 5 | 6 | $ sudo apt-get install build-essential libpcap-dev libnet1 libnet1-dev 7 | 8 | Under FreeBSD you will need to compile these libraries from ports: 9 | 10 | # cd /usr/ports/net/libnet-devel 11 | # make install 12 | # cd /usr/ports/net/libnet 13 | # make install 14 | 15 | Or install some packages with pkg_add ;-) 16 | 17 | 18 | Compilation 19 | ------------------------------------------------------------------------------- 20 | Also easy. Standard libc required. Just type: 21 | 22 | $ make clean && make 23 | 24 | 25 | Discovering 26 | ------------------------------------------------------------------------------- 27 | Run mactelnet with device name as an argument. It might take up several seconds 28 | to find all available hardware: 29 | 30 | # mactelnet eth0 31 | Discovering Mikrotik routers... (CTRL+C to abort) 32 | 00:0d:b9:12:d3:4c 2n_2c2_1_1 4.3 MikroTik up~263days21h x86 0.0.0.0 33 | 00:0d:b9:12:d3:4c 2n_2c2_1_1 4.3 MikroTik up~263days21h x86 0.0.0.0 34 | 35 | 36 | Connecting 37 | ------------------------------------------------------------------------------- 38 | Two arguments are required - device name and hardware MAC of previously 39 | discovered remote Mikrotik router. 40 | 41 | # mactelnet eth0 00:0d:b9:12:d3:4c 42 | Connecting to 00:0d:b9:12:d3:4c ... 43 | Username: admin 44 | Password: 45 | 46 | MikroTik RouterOS 2.9.27 (c) 1999-2006 http://www.mikrotik.com/ 47 | Terminal linux detected, using multiline input mode 48 | [admin@MikroTik] > 49 | 50 | 51 | Questions? 52 | ------------------------------------------------------------------------------- 53 | Don't hesitate to ask some questions. Feel free to write to elceef at itsec.pl 54 | 55 | -------------------------------------------------------------------------------- /mactelnet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MAC-Telnet - Telnet over Layer-2 3 | * -------------------------------- 4 | * Copyright (c) 2011 Marcin Ulikowski 5 | * 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #define _GNU_SOURCE 23 | #define VERSION "0.05" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "mndp.h" 31 | #include "protocol.h" 32 | #include "md5.h" 33 | 34 | 35 | static libnet_t *l; 36 | static u_int8_t *dstmac; 37 | static struct libnet_ether_addr *srcmac; 38 | static char libnet_errbuff[LIBNET_ERRBUF_SIZE]; 39 | 40 | static pcap_t *p; 41 | static int pcapfd; 42 | static struct bpf_program fp; 43 | static char libpcap_errbuff[PCAP_ERRBUF_SIZE]; 44 | 45 | static struct termios oflags, nflags; 46 | static struct winsize ws; 47 | static int sndrcv = 1; 48 | static u_int16_t sesskey; 49 | static u_int32_t outseq = 0, 50 | inseq = 0, 51 | keepcnt = 0; 52 | static u_int16_t srcport; 53 | static u_int8_t data[1500]; 54 | static unsigned char encryptkey[128]; 55 | static char username[64]; 56 | static char password[64]; 57 | 58 | 59 | static void bug(char *format, ...); 60 | static char* getpassword(const char *prompt); 61 | static int init_packet_header(u_int8_t *packet, u_int8_t ptype, u_int8_t *srcmac, u_int8_t *dstmac, u_int32_t cnt); 62 | static int init_control_packet_header(u_int8_t *packet, u_int8_t cptype, u_int32_t cplen); 63 | static void handle_mt(u_int8_t *args, struct pcap_pkthdr *header, u_int8_t *packet); 64 | static void handle_mndp(u_int8_t *args, struct pcap_pkthdr *header, u_int8_t *packet); 65 | static int send_frame(u_int8_t *dstmac, u_int16_t srcport, u_int16_t dstport, u_int8_t *payload, u_int16_t psize, u_int32_t retr); 66 | 67 | 68 | int main(int argc, char *argv[]) 69 | { 70 | int stat, i; 71 | fd_set fds; 72 | struct timeval timeout; 73 | 74 | if (argc < 2) { 75 | fprintf(stderr, "MAC-Telnet " VERSION "\n"); 76 | fprintf(stderr, "Usage: %s [ interface ] [ MAC address ]\n", argv[0]); 77 | fprintf(stderr, "Example: %s eth0 ee:11:cc:ee:ee:ff\n", argv[0]); 78 | exit(0); 79 | } 80 | 81 | if (!(p = pcap_open_live(argv[1], 1514, 0, 1, libpcap_errbuff))) 82 | bug("%s\n", libpcap_errbuff); 83 | 84 | if (!(l = libnet_init(LIBNET_LINK, argv[1], libnet_errbuff))) 85 | bug("%s\n", libnet_errbuff); 86 | 87 | if (argc == 2) // MNDP 88 | { 89 | printf("Discovering Mikrotik routers... (CTRL+C to abort)\n"); 90 | send_frame((u_int8_t *)"\xff\xff\xff\xff\xff\xff", 5678, 5678, (u_int8_t *)"\0\0\0\0", 4, 0); 91 | 92 | if (pcap_compile(p, &fp, "udp and port 5678 and len > 46", 1, 0)) 93 | bug("pcap_compile(): syntax error\n"); 94 | 95 | pcap_setfilter(p, &fp); 96 | 97 | pcap_loop(p, -1, (pcap_handler)&handle_mndp, 0); 98 | 99 | exit(0); 100 | } 101 | 102 | if (!(dstmac = libnet_hex_aton(argv[2], &i))) 103 | bug("%s\n", libnet_geterror(l)); 104 | 105 | if (!(srcmac = libnet_get_hwaddr(l))) 106 | bug("%s\n", libnet_geterror(l)); 107 | 108 | if (pcap_compile(p, &fp, "udp and src port 20561", 1, 0)) 109 | bug("pcap_compile(): syntax error\n"); 110 | 111 | pcap_setfilter(p, &fp); 112 | 113 | if (pcap_setnonblock(p, 1, libpcap_errbuff) == -1) 114 | fprintf(stderr, "%s", libpcap_errbuff); 115 | 116 | pcapfd = pcap_get_selectable_fd(p); 117 | // pcapfd = pcap_fileno(p); 118 | 119 | printf("Trying %02x:%02x:%02x:%02x:%02x:%02x ...\n", 120 | dstmac[0], dstmac[1], dstmac[2], dstmac[3], dstmac[4], dstmac[5]); 121 | 122 | printf("Username: "); 123 | scanf("%63s", username); 124 | 125 | char *tmpass; 126 | tmpass = getpassword("Password: "); 127 | strncpy(password, tmpass, sizeof(password) - 1); 128 | password[sizeof(password) - 1] = '\0'; 129 | bzero(tmpass, strlen(tmpass)); 130 | free(tmpass); 131 | 132 | srcport = libnet_get_prand(LIBNET_PRu16); 133 | sesskey = libnet_get_prand(LIBNET_PRu16); 134 | 135 | bzero(data, sizeof(data)); 136 | init_packet_header(data, MT_PTYPE_SESS_START, srcmac->ether_addr_octet, dstmac, 0); 137 | send_frame(dstmac, srcport, 20561, data, sizeof(struct mt_client_packet_hdr), 1); 138 | 139 | bzero(data, sizeof(data)); 140 | init_packet_header(data, MT_PTYPE_DATA, srcmac->ether_addr_octet, dstmac, 0); 141 | outseq += init_control_packet_header(data + sizeof(struct mt_client_packet_hdr), MT_CPTYPE_BEGINAUTH, 0); 142 | send_frame(dstmac, srcport, 20561, data, sizeof(struct mt_client_packet_hdr) + sizeof(struct mt_control_packet_hdr), 1); 143 | 144 | setvbuf(stdout, (char *)NULL, _IONBF, 0); 145 | 146 | while (sndrcv) { 147 | FD_ZERO(&fds); 148 | FD_SET(STDIN_FILENO, &fds); 149 | FD_SET(pcapfd, &fds); 150 | timeout.tv_sec = 1; 151 | timeout.tv_usec = 0; 152 | 153 | bzero(data, sizeof(data)); 154 | 155 | stat = select(pcapfd + 1, &fds, NULL, NULL, &timeout); 156 | 157 | if (stat > 0) 158 | { 159 | if (FD_ISSET(pcapfd, &fds)) 160 | { 161 | pcap_dispatch(p, 1, (pcap_handler)&handle_mt, (u_char *)NULL); 162 | } 163 | 164 | if (FD_ISSET(STDIN_FILENO, &fds)) 165 | { 166 | unsigned char buttons[256]; 167 | unsigned int bn; 168 | 169 | if ((bn = read(STDIN_FILENO, &buttons, sizeof(buttons))) <= 0) 170 | perror("read()"); 171 | 172 | init_packet_header(data, MT_PTYPE_DATA, srcmac->ether_addr_octet, dstmac, outseq); 173 | memcpy(&data[22], buttons, bn); 174 | 175 | outseq += bn; 176 | 177 | send_frame(dstmac, srcport, 20561, data, sizeof(struct mt_client_packet_hdr) + bn, 1); 178 | } 179 | } 180 | else 181 | { 182 | if (keepcnt++ == 10) { 183 | init_packet_header(data, MT_PTYPE_ACK, srcmac->ether_addr_octet, dstmac, outseq); 184 | send_frame(dstmac, srcport, 20561, data, sizeof(struct mt_client_packet_hdr), 0); 185 | } 186 | } 187 | } 188 | 189 | libnet_destroy(l); 190 | pcap_close(p); 191 | free(dstmac); 192 | 193 | printf("\nQuestions? Complaints? You can reach the author at \n"); 194 | 195 | return 0; 196 | } 197 | 198 | 199 | static void bug(char *format, ...) { 200 | char buffer[255]; 201 | va_list args; 202 | 203 | va_start(args, format); 204 | vsnprintf(buffer, sizeof(buffer) - 1, format, args); 205 | fprintf(stderr, "%s", buffer); 206 | va_end(args); 207 | 208 | exit(1); 209 | } 210 | 211 | 212 | static char* getpassword(const char *prompt) 213 | { 214 | char *ptr = malloc(256+1); 215 | char *p; 216 | sigset_t sig, sigsave; 217 | struct termios term, termsave; 218 | FILE *fp; 219 | int i = 0, c; 220 | 221 | if ( (fp = fopen(ctermid(NULL), "r+")) == NULL ) 222 | return NULL; 223 | setbuf(fp, NULL); 224 | 225 | sigemptyset(&sig); 226 | sigaddset(&sig, SIGINT); 227 | sigaddset(&sig, SIGTSTP); 228 | sigprocmask(SIG_BLOCK, &sig, &sigsave); 229 | 230 | tcgetattr(fileno(fp), &termsave); 231 | term = termsave; 232 | term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 233 | tcsetattr(fileno(fp), TCSAFLUSH, &term); 234 | 235 | fputs(prompt, fp); 236 | 237 | p = ptr; 238 | 239 | while ( (c = getc(fp)) != EOF && c != '\n') 240 | { 241 | if (i++ < 256) *ptr++ = c; 242 | } 243 | 244 | *ptr = 0; 245 | putc('\n', fp); 246 | 247 | tcsetattr(fileno(fp), TCSAFLUSH, &termsave); 248 | 249 | sigprocmask(SIG_SETMASK, &sigsave, NULL); 250 | fclose(fp); 251 | 252 | return p; 253 | } 254 | 255 | 256 | static void send_auth(char *user, char *pass) { 257 | u_int16_t width = 0, 258 | height = 0; 259 | char *terminal = getenv("TERM"); 260 | char md5data[100]; 261 | unsigned char md5sum[17]; 262 | u_int16_t plen = 0; 263 | md5_state_t state; 264 | 265 | md5data[0] = 0; 266 | strncpy(md5data + 1, pass, 82); 267 | md5data[83] = '\0'; 268 | memcpy(md5data + 1 + strlen(pass), encryptkey, 16); 269 | 270 | md5_init(&state); 271 | md5_append(&state, (const md5_byte_t *)md5data, strlen(pass) + 17); 272 | md5_finish(&state, (md5_byte_t *)md5sum + 1); 273 | md5sum[0] = 0; 274 | 275 | bzero(data, sizeof(data)); 276 | plen = init_packet_header(data, MT_PTYPE_DATA, srcmac->ether_addr_octet, dstmac, outseq); 277 | 278 | plen += init_control_packet_header(data + plen, MT_CPTYPE_PASSWORD, sizeof(md5sum)); 279 | memcpy(data + plen, md5sum, sizeof(md5sum)); 280 | plen += sizeof(md5sum); 281 | 282 | plen += init_control_packet_header(data + plen, MT_CPTYPE_USERNAME, strlen(user)); 283 | memcpy(data + plen, username, strlen(user)); 284 | plen += strlen(user); 285 | 286 | plen += init_control_packet_header(data + plen, MT_CPTYPE_TERM_TYPE, strlen(terminal)); 287 | memcpy(data + plen, terminal, strlen(terminal)); 288 | plen += strlen(terminal); 289 | 290 | if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) != 0) 291 | perror("ioctl()"); 292 | 293 | width = (ws.ws_col) ? ws.ws_col : 80; 294 | height = (ws.ws_row) ? ws.ws_row : 25; 295 | 296 | plen += init_control_packet_header(data + plen, MT_CPTYPE_TERM_WIDTH, 2); 297 | #if BYTE_ORDER == LITTLE_ENDIAN 298 | width = htons(width); 299 | #endif 300 | memcpy(data + plen, &width, 2); 301 | plen += 2; 302 | plen += init_control_packet_header(data + plen, MT_CPTYPE_TERM_HEIGHT, 2); 303 | #if BYTE_ORDER == LITTLE_ENDIAN 304 | height = htons(height); 305 | #endif 306 | memcpy(data + plen, &height, 2); 307 | plen += 2; 308 | 309 | send_frame(dstmac, srcport, 20561, data, plen, 1); 310 | 311 | outseq += plen - sizeof(struct mt_client_packet_hdr); 312 | } 313 | 314 | 315 | static int init_packet_header(u_int8_t *packet, u_int8_t ptype, u_int8_t *smac, u_int8_t *dmac, u_int32_t cnt) 316 | { 317 | struct mt_client_packet_hdr *mtp = (struct mt_client_packet_hdr *)packet; 318 | 319 | mtp->ver = 1; 320 | mtp->ptype = ptype; 321 | memcpy(mtp->srcmac, smac, 6); 322 | memcpy(mtp->dstmac, dmac, 6); 323 | #if BYTE_ORDER == LITTLE_ENDIAN 324 | mtp->sesskey = htons(sesskey); 325 | mtp->ctype = htons(MT_MACTELNET); 326 | mtp->seq = htonl(cnt); 327 | #else 328 | mtp->sesskey = sesskey; 329 | mtp->ctype = MT_MACTELNET; 330 | mtp->seq = cnt; 331 | #endif 332 | 333 | return sizeof(struct mt_client_packet_hdr); 334 | } 335 | 336 | 337 | static int init_control_packet_header(u_int8_t *packet, u_int8_t cptype, u_int32_t cplen) 338 | { 339 | struct mt_control_packet_hdr *mtcp = (struct mt_control_packet_hdr *)packet; 340 | 341 | mtcp->cpmagic = MT_CONTROL_MAGIC; 342 | mtcp->cptype = cptype; 343 | #if BYTE_ORDER == LITTLE_ENDIAN 344 | mtcp->cplen = htonl(cplen); 345 | #else 346 | mtcp->cplen = cplen; 347 | #endif 348 | return sizeof(struct mt_control_packet_hdr); 349 | } 350 | 351 | 352 | static void handle_mt(u_int8_t *args, struct pcap_pkthdr *header, u_int8_t *packet) 353 | { 354 | struct libnet_ipv4_hdr *ipv4_hdr; 355 | struct libnet_udp_hdr *udp_hdr; 356 | struct mt_server_packet_hdr *mtp_hdr; 357 | struct mt_control_packet_hdr *mtcp_hdr; 358 | u_int8_t *pdata; 359 | u_int32_t dlen; 360 | int i; 361 | 362 | ipv4_hdr = (struct libnet_ipv4_hdr *)(packet + sizeof(struct libnet_ethernet_hdr)); 363 | udp_hdr = (struct libnet_udp_hdr *)(packet + sizeof(struct libnet_ethernet_hdr) + (ipv4_hdr->ip_hl << 2)); 364 | mtp_hdr = (struct mt_server_packet_hdr *)(packet + sizeof(struct libnet_ethernet_hdr) + (ipv4_hdr->ip_hl << 2) + sizeof(struct libnet_udp_hdr)); 365 | pdata = (u_int8_t *)(packet + sizeof(struct libnet_ethernet_hdr) + (ipv4_hdr->ip_hl << 2) + sizeof(struct libnet_udp_hdr) + sizeof(struct mt_server_packet_hdr)); 366 | 367 | #if BYTE_ORDER == LITTLE_ENDIAN 368 | if (htons(mtp_hdr->sesskey) != sesskey) 369 | #else 370 | if (mtp_hdr->sesskey != sesskey) 371 | #endif 372 | { 373 | #ifdef __DEBUG 374 | fprintf(stderr, "Wrong session key!\n"); 375 | #endif 376 | return; 377 | } 378 | 379 | if (mtp_hdr->ptype == MT_PTYPE_DATA) 380 | { 381 | #if BYTE_ORDER == LITTLE_ENDIAN 382 | dlen = ntohs(ipv4_hdr->ip_len) - (ipv4_hdr->ip_hl << 2) - sizeof(struct libnet_udp_hdr) - sizeof(struct mt_server_packet_hdr); 383 | #else 384 | dlen = ipv4_hdr->ip_len - (ipv4_hdr->ip_hl << 2) - sizeof(struct libnet_udp_hdr) - sizeof(struct mt_server_packet_hdr); 385 | #endif 386 | 387 | bzero(data, sizeof(data)); 388 | #if BYTE_ORDER == LITTLE_ENDIAN 389 | init_packet_header(data, MT_PTYPE_ACK, srcmac->ether_addr_octet, dstmac, ntohl(mtp_hdr->seq) + dlen); 390 | #else 391 | init_packet_header(data, MT_PTYPE_ACK, srcmac->ether_addr_octet, dstmac, mtp_hdr->seq + dlen); 392 | #endif 393 | send_frame(dstmac, srcport, 20561, data, sizeof(struct mt_client_packet_hdr), 0); 394 | 395 | #if BYTE_ORDER == LITTLE_ENDIAN 396 | if (!inseq || ntohl(mtp_hdr->seq) > inseq || (inseq - ntohl(mtp_hdr->seq)) > 65535) 397 | { 398 | inseq = ntohl(mtp_hdr->seq); 399 | } else { 400 | return; 401 | } 402 | #else 403 | if (!inseq || mtp_hdr->seq > inseq || (inseq - mtp_hdr->seq) > 65535) 404 | { 405 | inseq = mtp_hdr->seq; 406 | } else { 407 | return; 408 | } 409 | #endif 410 | 411 | for (i = 0; i < dlen; i++) 412 | { 413 | mtcp_hdr = (struct mt_control_packet_hdr *)(packet + sizeof(struct libnet_ethernet_hdr) + (ipv4_hdr->ip_hl << 2) + sizeof(struct libnet_udp_hdr) + sizeof(struct mt_server_packet_hdr) + i); 414 | 415 | if (mtcp_hdr->cpmagic == MT_CONTROL_MAGIC) // control data 416 | { 417 | if (mtcp_hdr->cptype == MT_CPTYPE_ENCRYPTKEY) 418 | { 419 | #if BYTE_ORDER == LITTLE_ENDIAN 420 | memcpy(&encryptkey, pdata + sizeof(struct mt_control_packet_hdr), ntohl(mtcp_hdr->cplen)); 421 | #else 422 | memcpy(&encryptkey, pdata + sizeof(struct mt_control_packet_hdr), mtcp_hdr->cplen); 423 | #endif 424 | send_auth(username, password); 425 | } 426 | else 427 | if (mtcp_hdr->cptype == MT_CPTYPE_ENDAUTH) 428 | { 429 | if (tcgetattr(STDIN_FILENO, &oflags) < 0) 430 | perror("tcgetattr()"); 431 | 432 | memcpy(&nflags, &oflags, sizeof(struct termios)); 433 | 434 | cfmakeraw(&nflags); 435 | 436 | if (tcsetattr(STDIN_FILENO, TCSANOW, &nflags) < 0) 437 | perror("tcsetattr()"); 438 | 439 | setvbuf(stdin, (char *)NULL, _IONBF, 0); 440 | } 441 | } 442 | else 443 | { 444 | printf("%s", pdata); 445 | break; 446 | } 447 | 448 | i += mtcp_hdr->cplen + sizeof(struct mt_control_packet_hdr) - 1; 449 | } 450 | } 451 | else 452 | if (mtp_hdr->ptype == MT_PTYPE_ACK) 453 | { 454 | //TODO: 455 | } 456 | else 457 | if (mtp_hdr->ptype == MT_PTYPE_SESS_END) 458 | { 459 | bzero(data, sizeof(data)); 460 | init_packet_header(data, MT_PTYPE_SESS_END, srcmac->ether_addr_octet, dstmac, 0); 461 | send_frame(dstmac, srcport, 20561, data, sizeof(struct mt_client_packet_hdr), 0); 462 | 463 | fprintf(stderr, "\nConnection closed.\n"); 464 | 465 | if (tcsetattr(STDIN_FILENO, TCSANOW, &oflags) < 0) 466 | perror("tcsetattr()"); 467 | 468 | sndrcv = 0; 469 | } 470 | else 471 | { 472 | #ifdef __DEBUG 473 | fprintf(stderr, "Unhandled packet type: %d\n", mtp_hdr->ptype); 474 | #endif 475 | } 476 | } 477 | 478 | 479 | static void handle_mndp(u_int8_t *args, struct pcap_pkthdr *header, u_int8_t *packet) 480 | { 481 | struct libnet_ipv4_hdr *ipv4_hdr; 482 | struct libnet_udp_hdr *udp_hdr; 483 | struct mndp_header *mndp_hdr; 484 | 485 | ipv4_hdr = (struct libnet_ipv4_hdr *)(packet + sizeof(struct libnet_ethernet_hdr)); 486 | udp_hdr = (struct libnet_udp_hdr *)(packet + sizeof(struct libnet_ethernet_hdr) + (ipv4_hdr->ip_hl << 2)); 487 | mndp_hdr = (struct mndp_header *)(packet + sizeof(struct libnet_ethernet_hdr) + (ipv4_hdr->ip_hl << 2) + sizeof(struct libnet_udp_hdr)); 488 | 489 | int i, j; 490 | u_int8_t *p; 491 | u_int16_t type, len, uh_ulen; 492 | u_int32_t ip; 493 | 494 | #if BYTE_ORDER == LITTLE_ENDIAN 495 | uh_ulen = htons(udp_hdr->uh_ulen); 496 | #else 497 | uh_ulen = udp_hdr->uh_ulen; 498 | #endif 499 | 500 | p = (u_int8_t *)(packet + sizeof(struct libnet_ethernet_hdr) + (ipv4_hdr->ip_hl << 2) + sizeof(struct libnet_udp_hdr) + sizeof(struct mndp_header)); 501 | 502 | for (i = 0; i < (uh_ulen - sizeof(struct libnet_udp_hdr) - 4); i++) { 503 | 504 | memcpy(&type, p, 2); 505 | memcpy(&len, p+2, 2); 506 | #if BYTE_ORDER == LITTLE_ENDIAN 507 | type = ntohs(type); 508 | len = ntohs(len); 509 | #endif 510 | p+=4; 511 | 512 | switch (type) { 513 | 514 | case MNDP_TYPE_ADDRESS: 515 | printf("%02x:%02x:%02x:%02x:%02x:%02x ", *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5)); 516 | break; 517 | 518 | case MNDP_TYPE_IDENTITY: 519 | case MNDP_TYPE_VERSION: 520 | case MNDP_TYPE_PLATFORM: 521 | #ifdef __DEBUG 522 | case MNDP_TYPE_SOFTID: 523 | #endif 524 | case MNDP_TYPE_CPUARCH: 525 | for (j = 0; j < len; j++) { 526 | putchar(*(p+j)); 527 | } 528 | putchar(' '); 529 | break; 530 | 531 | case MNDP_TYPE_TIMESTAMP: 532 | memcpy(&j, p, 4); 533 | printf("up~%udays%uh ", j/86400, j%86400/3600); 534 | break; 535 | 536 | default: 537 | #ifdef __DEBUG 538 | printf("type=%04x len=%u val=", type, len); 539 | for (j = 0; j < len; j++) { 540 | printf("%02x", *(p+j)); 541 | } 542 | putchar('|'); 543 | for (j = 0; j < len; j++) { 544 | if (*(p+j) >= 32 && *(p+j) < 128) 545 | { 546 | putchar(*(p+j)); 547 | } else { 548 | putchar('.'); 549 | } 550 | } 551 | putchar(' '); 552 | #endif 553 | break; 554 | } 555 | 556 | p += len; 557 | i += len + 3; 558 | } 559 | 560 | memcpy(&ip, &ipv4_hdr->ip_src.s_addr, 4); 561 | #if BYTE_ORDER == LITTLE_ENDIAN 562 | ip = ntohl(ip); 563 | #endif 564 | p = (u_int8_t *)&ip; 565 | printf("%u.%u.%u.%u\n", p[3], p[2], p[1], p[0]); 566 | } 567 | 568 | 569 | static int send_frame(u_int8_t *dmac, u_int16_t sport, u_int16_t dport, u_int8_t *payload, u_int16_t psize, u_int32_t retr) 570 | { 571 | unsigned int i, bytes; 572 | 573 | keepcnt = 0; 574 | 575 | libnet_build_udp 576 | ( 577 | sport, 578 | dport, 579 | LIBNET_UDP_H + psize, 580 | 0, 581 | payload, 582 | psize, 583 | l, 584 | 0 585 | ); 586 | 587 | libnet_build_ipv4 588 | ( 589 | LIBNET_UDP_H + LIBNET_IPV4_H + psize, // length 590 | 0, // ToS 591 | 0, // id autogenerated 592 | 0, // fragmentation bits & offset 593 | 64, // TTL 594 | IPPROTO_UDP, 595 | 0, // checksum autogenerated 596 | 0, // srcip = 0.0.0.0 597 | 4294967295U, // dstip = 255.255.255.255 598 | NULL, 599 | 0, 600 | l, 601 | 0 602 | ); 603 | 604 | 605 | libnet_autobuild_ethernet 606 | ( 607 | dmac, 608 | ETHERTYPE_IP, 609 | l 610 | ); 611 | 612 | bytes = libnet_write(l); 613 | libnet_clear_packet(l); 614 | 615 | if (retr) //TODO: stop only if ACK 616 | { 617 | for (i = 0; i < 9; ++i) 618 | { 619 | fd_set rfds; 620 | int stat = 0; 621 | struct timeval timeout; 622 | int intval = retr_intval[i] * 1000; 623 | 624 | FD_ZERO(&rfds); 625 | FD_SET(pcapfd, &rfds); 626 | timeout.tv_sec = 0; 627 | timeout.tv_usec = intval; 628 | 629 | stat = select(pcapfd + 1, &rfds, NULL, NULL, &timeout); 630 | 631 | if (stat && FD_ISSET(pcapfd, &rfds)) { 632 | return bytes; 633 | } 634 | 635 | send_frame(dmac, sport, dport, payload, psize, 0); 636 | } 637 | 638 | fprintf(stderr, "\nConnection timed out\n"); 639 | exit(1); 640 | } 641 | 642 | return bytes; 643 | } 644 | -------------------------------------------------------------------------------- /md5.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | L. Peter Deutsch 21 | ghost@aladdin.com 22 | 23 | */ 24 | /* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ 25 | /* 26 | Independent implementation of MD5 (RFC 1321). 27 | 28 | This code implements the MD5 Algorithm defined in RFC 1321, whose 29 | text is available at 30 | http://www.ietf.org/rfc/rfc1321.txt 31 | The code is derived from the text of the RFC, including the test suite 32 | (section A.5) but excluding the rest of Appendix A. It does not include 33 | any code or documentation that is identified in the RFC as being 34 | copyrighted. 35 | 36 | The original and principal author of md5.c is L. Peter Deutsch 37 | . Other authors are noted in the change history 38 | that follows (in reverse chronological order): 39 | 40 | 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order 41 | either statically or dynamically; added missing #include 42 | in library. 43 | 2002-03-11 lpd Corrected argument list for main(), and added int return 44 | type, in test program and T value program. 45 | 2002-02-21 lpd Added missing #include in test program. 46 | 2000-07-03 lpd Patched to eliminate warnings about "constant is 47 | unsigned in ANSI C, signed in traditional"; made test program 48 | self-checking. 49 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 50 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 51 | 1999-05-03 lpd Original version. 52 | */ 53 | 54 | #include "md5.h" 55 | #include 56 | 57 | #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ 58 | #ifdef ARCH_IS_BIG_ENDIAN 59 | # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) 60 | #else 61 | # define BYTE_ORDER 0 62 | #endif 63 | 64 | #define T_MASK ((md5_word_t)~0) 65 | #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) 66 | #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) 67 | #define T3 0x242070db 68 | #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) 69 | #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) 70 | #define T6 0x4787c62a 71 | #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) 72 | #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) 73 | #define T9 0x698098d8 74 | #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) 75 | #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) 76 | #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) 77 | #define T13 0x6b901122 78 | #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) 79 | #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) 80 | #define T16 0x49b40821 81 | #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) 82 | #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) 83 | #define T19 0x265e5a51 84 | #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) 85 | #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) 86 | #define T22 0x02441453 87 | #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) 88 | #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) 89 | #define T25 0x21e1cde6 90 | #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) 91 | #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) 92 | #define T28 0x455a14ed 93 | #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) 94 | #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) 95 | #define T31 0x676f02d9 96 | #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) 97 | #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) 98 | #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) 99 | #define T35 0x6d9d6122 100 | #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) 101 | #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) 102 | #define T38 0x4bdecfa9 103 | #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) 104 | #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) 105 | #define T41 0x289b7ec6 106 | #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) 107 | #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) 108 | #define T44 0x04881d05 109 | #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) 110 | #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) 111 | #define T47 0x1fa27cf8 112 | #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) 113 | #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) 114 | #define T50 0x432aff97 115 | #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) 116 | #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) 117 | #define T53 0x655b59c3 118 | #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) 119 | #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) 120 | #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) 121 | #define T57 0x6fa87e4f 122 | #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) 123 | #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) 124 | #define T60 0x4e0811a1 125 | #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) 126 | #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) 127 | #define T63 0x2ad7d2bb 128 | #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) 129 | 130 | 131 | static void 132 | md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) 133 | { 134 | md5_word_t 135 | a = pms->abcd[0], b = pms->abcd[1], 136 | c = pms->abcd[2], d = pms->abcd[3]; 137 | md5_word_t t; 138 | #if BYTE_ORDER > 0 139 | /* Define storage only for big-endian CPUs. */ 140 | md5_word_t X[16]; 141 | #else 142 | /* Define storage for little-endian or both types of CPUs. */ 143 | md5_word_t xbuf[16]; 144 | const md5_word_t *X; 145 | #endif 146 | 147 | { 148 | #if BYTE_ORDER == 0 149 | /* 150 | * Determine dynamically whether this is a big-endian or 151 | * little-endian machine, since we can use a more efficient 152 | * algorithm on the latter. 153 | */ 154 | static const int w = 1; 155 | 156 | if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ 157 | #endif 158 | #if BYTE_ORDER <= 0 /* little-endian */ 159 | { 160 | /* 161 | * On little-endian machines, we can process properly aligned 162 | * data without copying it. 163 | */ 164 | if (!((data - (const md5_byte_t *)0) & 3)) { 165 | /* data are properly aligned */ 166 | X = (const md5_word_t *)data; 167 | } else { 168 | /* not aligned */ 169 | memcpy(xbuf, data, 64); 170 | X = xbuf; 171 | } 172 | } 173 | #endif 174 | #if BYTE_ORDER == 0 175 | else /* dynamic big-endian */ 176 | #endif 177 | #if BYTE_ORDER >= 0 /* big-endian */ 178 | { 179 | /* 180 | * On big-endian machines, we must arrange the bytes in the 181 | * right order. 182 | */ 183 | const md5_byte_t *xp = data; 184 | int i; 185 | 186 | # if BYTE_ORDER == 0 187 | X = xbuf; /* (dynamic only) */ 188 | # else 189 | # define xbuf X /* (static only) */ 190 | # endif 191 | for (i = 0; i < 16; ++i, xp += 4) 192 | xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); 193 | } 194 | #endif 195 | } 196 | 197 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 198 | 199 | /* Round 1. */ 200 | /* Let [abcd k s i] denote the operation 201 | a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ 202 | #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) 203 | #define SET(a, b, c, d, k, s, Ti)\ 204 | t = a + F(b,c,d) + X[k] + Ti;\ 205 | a = ROTATE_LEFT(t, s) + b 206 | /* Do the following 16 operations. */ 207 | SET(a, b, c, d, 0, 7, T1); 208 | SET(d, a, b, c, 1, 12, T2); 209 | SET(c, d, a, b, 2, 17, T3); 210 | SET(b, c, d, a, 3, 22, T4); 211 | SET(a, b, c, d, 4, 7, T5); 212 | SET(d, a, b, c, 5, 12, T6); 213 | SET(c, d, a, b, 6, 17, T7); 214 | SET(b, c, d, a, 7, 22, T8); 215 | SET(a, b, c, d, 8, 7, T9); 216 | SET(d, a, b, c, 9, 12, T10); 217 | SET(c, d, a, b, 10, 17, T11); 218 | SET(b, c, d, a, 11, 22, T12); 219 | SET(a, b, c, d, 12, 7, T13); 220 | SET(d, a, b, c, 13, 12, T14); 221 | SET(c, d, a, b, 14, 17, T15); 222 | SET(b, c, d, a, 15, 22, T16); 223 | #undef SET 224 | 225 | /* Round 2. */ 226 | /* Let [abcd k s i] denote the operation 227 | a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ 228 | #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) 229 | #define SET(a, b, c, d, k, s, Ti)\ 230 | t = a + G(b,c,d) + X[k] + Ti;\ 231 | a = ROTATE_LEFT(t, s) + b 232 | /* Do the following 16 operations. */ 233 | SET(a, b, c, d, 1, 5, T17); 234 | SET(d, a, b, c, 6, 9, T18); 235 | SET(c, d, a, b, 11, 14, T19); 236 | SET(b, c, d, a, 0, 20, T20); 237 | SET(a, b, c, d, 5, 5, T21); 238 | SET(d, a, b, c, 10, 9, T22); 239 | SET(c, d, a, b, 15, 14, T23); 240 | SET(b, c, d, a, 4, 20, T24); 241 | SET(a, b, c, d, 9, 5, T25); 242 | SET(d, a, b, c, 14, 9, T26); 243 | SET(c, d, a, b, 3, 14, T27); 244 | SET(b, c, d, a, 8, 20, T28); 245 | SET(a, b, c, d, 13, 5, T29); 246 | SET(d, a, b, c, 2, 9, T30); 247 | SET(c, d, a, b, 7, 14, T31); 248 | SET(b, c, d, a, 12, 20, T32); 249 | #undef SET 250 | 251 | /* Round 3. */ 252 | /* Let [abcd k s t] denote the operation 253 | a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ 254 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 255 | #define SET(a, b, c, d, k, s, Ti)\ 256 | t = a + H(b,c,d) + X[k] + Ti;\ 257 | a = ROTATE_LEFT(t, s) + b 258 | /* Do the following 16 operations. */ 259 | SET(a, b, c, d, 5, 4, T33); 260 | SET(d, a, b, c, 8, 11, T34); 261 | SET(c, d, a, b, 11, 16, T35); 262 | SET(b, c, d, a, 14, 23, T36); 263 | SET(a, b, c, d, 1, 4, T37); 264 | SET(d, a, b, c, 4, 11, T38); 265 | SET(c, d, a, b, 7, 16, T39); 266 | SET(b, c, d, a, 10, 23, T40); 267 | SET(a, b, c, d, 13, 4, T41); 268 | SET(d, a, b, c, 0, 11, T42); 269 | SET(c, d, a, b, 3, 16, T43); 270 | SET(b, c, d, a, 6, 23, T44); 271 | SET(a, b, c, d, 9, 4, T45); 272 | SET(d, a, b, c, 12, 11, T46); 273 | SET(c, d, a, b, 15, 16, T47); 274 | SET(b, c, d, a, 2, 23, T48); 275 | #undef SET 276 | 277 | /* Round 4. */ 278 | /* Let [abcd k s t] denote the operation 279 | a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ 280 | #define I(x, y, z) ((y) ^ ((x) | ~(z))) 281 | #define SET(a, b, c, d, k, s, Ti)\ 282 | t = a + I(b,c,d) + X[k] + Ti;\ 283 | a = ROTATE_LEFT(t, s) + b 284 | /* Do the following 16 operations. */ 285 | SET(a, b, c, d, 0, 6, T49); 286 | SET(d, a, b, c, 7, 10, T50); 287 | SET(c, d, a, b, 14, 15, T51); 288 | SET(b, c, d, a, 5, 21, T52); 289 | SET(a, b, c, d, 12, 6, T53); 290 | SET(d, a, b, c, 3, 10, T54); 291 | SET(c, d, a, b, 10, 15, T55); 292 | SET(b, c, d, a, 1, 21, T56); 293 | SET(a, b, c, d, 8, 6, T57); 294 | SET(d, a, b, c, 15, 10, T58); 295 | SET(c, d, a, b, 6, 15, T59); 296 | SET(b, c, d, a, 13, 21, T60); 297 | SET(a, b, c, d, 4, 6, T61); 298 | SET(d, a, b, c, 11, 10, T62); 299 | SET(c, d, a, b, 2, 15, T63); 300 | SET(b, c, d, a, 9, 21, T64); 301 | #undef SET 302 | 303 | /* Then perform the following additions. (That is increment each 304 | of the four registers by the value it had before this block 305 | was started.) */ 306 | pms->abcd[0] += a; 307 | pms->abcd[1] += b; 308 | pms->abcd[2] += c; 309 | pms->abcd[3] += d; 310 | } 311 | 312 | void 313 | md5_init(md5_state_t *pms) 314 | { 315 | pms->count[0] = pms->count[1] = 0; 316 | pms->abcd[0] = 0x67452301; 317 | pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; 318 | pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; 319 | pms->abcd[3] = 0x10325476; 320 | } 321 | 322 | void 323 | md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) 324 | { 325 | const md5_byte_t *p = data; 326 | int left = nbytes; 327 | int offset = (pms->count[0] >> 3) & 63; 328 | md5_word_t nbits = (md5_word_t)(nbytes << 3); 329 | 330 | if (nbytes <= 0) 331 | return; 332 | 333 | /* Update the message length. */ 334 | pms->count[1] += nbytes >> 29; 335 | pms->count[0] += nbits; 336 | if (pms->count[0] < nbits) 337 | pms->count[1]++; 338 | 339 | /* Process an initial partial block. */ 340 | if (offset) { 341 | int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); 342 | 343 | memcpy(pms->buf + offset, p, copy); 344 | if (offset + copy < 64) 345 | return; 346 | p += copy; 347 | left -= copy; 348 | md5_process(pms, pms->buf); 349 | } 350 | 351 | /* Process full blocks. */ 352 | for (; left >= 64; p += 64, left -= 64) 353 | md5_process(pms, p); 354 | 355 | /* Process a final partial block. */ 356 | if (left) 357 | memcpy(pms->buf, p, left); 358 | } 359 | 360 | void 361 | md5_finish(md5_state_t *pms, md5_byte_t digest[16]) 362 | { 363 | static const md5_byte_t pad[64] = { 364 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 365 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 366 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 367 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 368 | }; 369 | md5_byte_t data[8]; 370 | int i; 371 | 372 | /* Save the length before padding. */ 373 | for (i = 0; i < 8; ++i) 374 | data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); 375 | /* Pad to 56 bytes mod 64. */ 376 | md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); 377 | /* Append the length. */ 378 | md5_append(pms, data, 8); 379 | for (i = 0; i < 16; ++i) 380 | digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); 381 | } 382 | -------------------------------------------------------------------------------- /md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | L. Peter Deutsch 21 | ghost@aladdin.com 22 | 23 | */ 24 | /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ 25 | /* 26 | Independent implementation of MD5 (RFC 1321). 27 | 28 | This code implements the MD5 Algorithm defined in RFC 1321, whose 29 | text is available at 30 | http://www.ietf.org/rfc/rfc1321.txt 31 | The code is derived from the text of the RFC, including the test suite 32 | (section A.5) but excluding the rest of Appendix A. It does not include 33 | any code or documentation that is identified in the RFC as being 34 | copyrighted. 35 | 36 | The original and principal author of md5.h is L. Peter Deutsch 37 | . Other authors are noted in the change history 38 | that follows (in reverse chronological order): 39 | 40 | 2002-04-13 lpd Removed support for non-ANSI compilers; removed 41 | references to Ghostscript; clarified derivation from RFC 1321; 42 | now handles byte order either statically or dynamically. 43 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 44 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); 45 | added conditionalization for C++ compilation from Martin 46 | Purschke . 47 | 1999-05-03 lpd Original version. 48 | */ 49 | 50 | #ifndef md5_INCLUDED 51 | # define md5_INCLUDED 52 | 53 | /* 54 | * This package supports both compile-time and run-time determination of CPU 55 | * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be 56 | * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is 57 | * defined as non-zero, the code will be compiled to run only on big-endian 58 | * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to 59 | * run on either big- or little-endian CPUs, but will run slightly less 60 | * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. 61 | */ 62 | 63 | typedef unsigned char md5_byte_t; /* 8-bit byte */ 64 | typedef unsigned int md5_word_t; /* 32-bit word */ 65 | 66 | /* Define the state of the MD5 Algorithm. */ 67 | typedef struct md5_state_s { 68 | md5_word_t count[2]; /* message length in bits, lsw first */ 69 | md5_word_t abcd[4]; /* digest buffer */ 70 | md5_byte_t buf[64]; /* accumulate block */ 71 | } md5_state_t; 72 | 73 | #ifdef __cplusplus 74 | extern "C" 75 | { 76 | #endif 77 | 78 | /* Initialize the algorithm. */ 79 | void md5_init(md5_state_t *pms); 80 | 81 | /* Append a string to the message. */ 82 | void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); 83 | 84 | /* Finish the message and return the digest. */ 85 | void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); 86 | 87 | #ifdef __cplusplus 88 | } /* end extern "C" */ 89 | #endif 90 | 91 | #endif /* md5_INCLUDED */ 92 | -------------------------------------------------------------------------------- /mndp.h: -------------------------------------------------------------------------------- 1 | #define MNDP_TYPE_ADDRESS 0x0001 2 | #define MNDP_TYPE_IDENTITY 0x0005 3 | #define MNDP_TYPE_VERSION 0x0007 4 | #define MNDP_TYPE_PLATFORM 0x0008 5 | #define MNDP_TYPE_TIMESTAMP 0x000a 6 | #define MNDP_TYPE_SOFTID 0x000b 7 | #define MNDP_TYPE_CPUARCH 0x000c 8 | 9 | struct mndp_header { 10 | u_int8_t version; 11 | u_int8_t ttl; 12 | u_int16_t cksum; 13 | }; 14 | -------------------------------------------------------------------------------- /protocol.h: -------------------------------------------------------------------------------- 1 | static const int retr_intval[9] = { 15, 30, 60, 100, 150, 170, 350, 650, 1000 }; 2 | 3 | #define MT_MACTELNET 21 // 0x0015 4 | #define MT_CONTROL_MAGIC 4279383126U 5 | 6 | /* Packet Type */ 7 | #define MT_PTYPE_SESS_START 0 8 | #define MT_PTYPE_DATA 1 9 | #define MT_PTYPE_ACK 2 10 | #define MT_PTYPE_SESS_END 255 11 | 12 | /* Control section */ 13 | #define MT_CPTYPE_BEGINAUTH 0 14 | #define MT_CPTYPE_ENCRYPTKEY 1 15 | #define MT_CPTYPE_PASSWORD 2 16 | #define MT_CPTYPE_USERNAME 3 17 | #define MT_CPTYPE_TERM_TYPE 4 18 | #define MT_CPTYPE_TERM_WIDTH 5 19 | #define MT_CPTYPE_TERM_HEIGHT 6 20 | #define MT_CPTYPE_PACKET_ERROR 7 21 | #define MT_CPTYPE_ENDAUTH 9 22 | 23 | 24 | struct __attribute__((packed)) mt_client_packet_hdr 25 | { 26 | u_int8_t ver, 27 | ptype; 28 | u_int8_t srcmac[6], 29 | dstmac[6]; 30 | u_int16_t sesskey, 31 | ctype; 32 | u_int32_t seq; 33 | }; 34 | 35 | struct __attribute__((packed)) mt_server_packet_hdr 36 | { 37 | u_int8_t ver, 38 | ptype; 39 | u_int8_t srcmac[6], 40 | dstmac[6]; 41 | u_int16_t ctype, 42 | sesskey; 43 | u_int32_t seq; 44 | }; 45 | 46 | struct __attribute__((packed)) mt_control_packet_hdr 47 | { 48 | u_int32_t cpmagic; 49 | u_int8_t cptype; 50 | u_int32_t cplen; 51 | }; 52 | --------------------------------------------------------------------------------