MYSQL *mysql_real_connect( MYSQL *m, const char *host, const char *user, const char *pass, void *unused, int port, const char *socket, int options ) { PHOST h; char scramble_buf[21]; MYSQL_PACKET *p = &m->packet; int pcount = 1; if( socket && *socket ) { error(m,"Unix Socket connections are not supported",NULL); return NULL; } h = phost_resolve(host); if( h == UNRESOLVED_HOST ) { error(m,"Failed to resolve host '%s'",host); return NULL; } m->s = psock_create(); if( m->s == INVALID_SOCKET ) { error(m,"Failed to create socket",NULL); return NULL; } psock_set_fastsend(m->s,1); psock_set_timeout(m->s,50); // 50 seconds if( psock_connect(m->s,h,port) != PS_OK ) { myp_close(m); error(m,"Failed to connect on host '%s'",host); return NULL; } if( !myp_read_packet(m,p) ) { myp_close(m); error(m,"Failed to read handshake packet",NULL); return NULL; } // process handshake packet { char filler[13]; unsigned int len; m->infos.proto_version = myp_read_byte(p); // this seems like an error packet if( m->infos.proto_version == 0xFF ) { myp_close(m); save_error(m,p); return NULL; } m->infos.server_version = strdup(myp_read_string(p)); m->infos.thread_id = myp_read_int(p); myp_read(p,scramble_buf,8); myp_read_byte(p); // should be 0 m->infos.server_flags = myp_read_ui16(p); m->infos.server_charset = myp_read_byte(p); m->infos.server_status = myp_read_ui16(p); m->infos.server_flags |= myp_read_ui16(p) << 16; len = myp_read_byte(p); myp_read(p,filler,10); // try to disable 41 m->is41 = (m->infos.server_flags & FL_PROTOCOL_41) != 0; if( !p->error && m->is41 ) myp_read(p,scramble_buf + 8,13); if( p->pos != p->size ) myp_read_string(p); // 5.5+ if( p->error ) { myp_close(m); error(m,"Failed to decode server handshake",NULL); return NULL; } // fill answer packet { unsigned int flags = m->infos.server_flags; int max_packet_size = 0x01000000; SHA1_DIGEST hpass; char filler[23]; flags &= (FL_PROTOCOL_41 | FL_TRANSACTIONS | FL_SECURE_CONNECTION); myp_begin_packet(p,128); if( m->is41 ) { myp_write_int(p,flags); myp_write_int(p,max_packet_size); myp_write_byte(p,m->infos.server_charset); memset(filler,0,23); myp_write(p,filler,23); myp_write_string(p,user); if( *pass ) { myp_encrypt_password(pass,scramble_buf,hpass); myp_write_bin(p,SHA1_SIZE); myp_write(p,hpass,SHA1_SIZE); myp_write_byte(p,0); } else myp_write_bin(p,0); } else { myp_write_ui16(p,flags); // max_packet_size myp_write_byte(p,0xFF); myp_write_byte(p,0xFF); myp_write_byte(p,0xFF); myp_write_string(p,user); if( *pass ) { char hpass[SEED_LENGTH_323 + 1]; myp_encrypt_pass_323(pass,scramble_buf,hpass); hpass[SEED_LENGTH_323] = 0; myp_write(p,hpass,SEED_LENGTH_323 + 1); } else myp_write_bin(p,0); } } } // send connection packet send_cnx_packet: if( !myp_send_packet(m,p,&pcount) ) { myp_close(m); error(m,"Failed to send connection packet",NULL); return NULL; } // read answer packet if( !myp_read_packet(m,p) ) { myp_close(m); error(m,"Failed to read packet",NULL); return NULL; } // increase packet counter (because we read one packet) pcount++; // process answer { int code = myp_read_byte(p); switch( code ) { case 0: // OK packet break; case 0xFF: // ERROR myp_close(m); save_error(m,p); return NULL; case 0xFE: // EOF // we are asked to send old password authentification if( p->size == 1 ) { char hpass[SEED_LENGTH_323 + 1]; myp_encrypt_pass_323(pass,scramble_buf,hpass); hpass[SEED_LENGTH_323] = 0; myp_begin_packet(p,0); myp_write(p,hpass,SEED_LENGTH_323 + 1); goto send_cnx_packet; } // fallthrough default: myp_close(m); error(m,"Invalid packet error",NULL); return NULL; } } // we are connected, setup a longer timeout psock_set_timeout(m->s,18000); return m; }
int netpkt_main(int argc, char **argv) { int sd; int i; int txc; int rxc; uint8_t *buf; const int buflen = 128; const char da[6] = {0xf0, 0xde, 0xf1, 0x02, 0x43, 0x01}; const char sa[6] = {0x00, 0xe0, 0xde, 0xad, 0xbe, 0xef}; int opt; int verbose = 0; int do_rx = 0; int do_rxtimes = 3; int do_tx = 0; int do_txtimes = 3; if (argc == 1) { netpkt_usage(); return -1; } /* Parse arguments */ while ((opt = getopt(argc, argv, "artv")) != -1) { switch(opt) { case 'a': do_rx = 1; do_tx = 1; break; case 'r': do_rx = 1; break; case 't': do_tx = 1; break; case 'v': verbose = 1; break; default: netpkt_usage(); return -1; } } sd = psock_create(); if (do_tx) { if (verbose) { printf("Testing write() (%d times)\n", do_txtimes); } buf = malloc(buflen); memset(buf, 0, buflen); memcpy(buf, da, 6); memcpy(buf+6, sa, 6); for (i = 0; i < do_txtimes; i++) { if ((txc = write(sd, buf, buflen)) < 0) { perror("ERROR: write failed"); free(buf); close(sd); return -1; } else { if (verbose) { printf("transmited %d octets\n", txc); print_buf(buf, txc); } } } free(buf); } if (do_rx) { if (verbose) { printf("Testing read() (%d times)\n", do_rxtimes); } buf = malloc(buflen); memset(buf, 0, buflen); for (i = 0; i < do_rxtimes; i++) { rxc = read(sd, buf, buflen); if (rxc < 0) { perror("ERROR: read failed"); free(buf); close(sd); return -1; } else if (rxc == 0) { /* ignore silently */ } else { if (verbose) { printf("received %d octets\n", rxc); print_buf(buf, rxc); } } } free(buf); } close(sd); return 0; }