#include #include #include #include #include "usbdevice.h" #include "rndis.h" #include "network_interface.h" #include #include #include "stringutils.h" #include "vectorutils.h" #include "pipe_ipc_clt.h" #define IPCCLIENT pipe_ipc_client // see ~/gitprj/repos/pptp/pptp-linux/pptp.c // todo: copy code from pptp, to hook to pppd // // notes on installing synce: // * install macport: dbus-glib // * install macport: gnet2 // * install macport: libtool // * in librapi2/bootstrap, change libtoolize to 'glibtoolize' // * in libsynce: autogen.sh --disable-hal-support --with-libiconv-prefix // * then: make // * in librapi: LIBSYNCE_CFLAGS=-I$(pwd)/../libsynce/lib/ LIBSYNCE_LIBS="-L$(pwd)/../libsynce/lib/.libs/" bash autogen.sh --disable-hal-support // * in odccm: LIBSYNCE_CFLAGS=-I$(pwd)/../libsynce/lib/ LIBSYNCE_LIBS="-L$(pwd)/../libsynce/lib/.libs/" bash autogen.sh // * then edit src/Makefile and remove @HAL_\w*@ // * then: make // -> problem: needs 'hal' // bool g_launchpppd= true; // note normal order of communication: // 1) device sends 'CLIENT' // 2) pc replies with 'CLIENTSERVER' // 3) device sends LCP ConfReq // 4) pc replies LCP ConfAck // 5) pc sends LCP ConfReq // 6) device replies LCP ConfAck // // 7) pc sends IPCP ConfReq // ... void handle_client_server_handshake(usbdev& ph) { while (true) { sleep(1); // todo: get '0x200' from max_packet_size ByteVector buf(0x200); size_t n; while ((n= ph.bulkread(buf.begin(), buf.end()))!=0) { buf.resize(n); printf("RECV: %s\n", ascdump(buf).c_str()); if (n==6 && memcmp(&buf.front(), "CLIENT", 6)==0) { fprintf(stderr,"client detected\n"); const uint8_t *cs= (const uint8_t *)"CLIENTSERVER"; ph.bulkwrite(cs, cs+12); return; } else { fprintf(stderr,"non CLIENT received - dropping first ppp frame\n"); return; } buf.resize(0x200); } } } struct copy_pipe2usb { usbdev& _ph; IPCCLIENT& _pp; copy_pipe2usb(usbdev& ph, IPCCLIENT& pp) : _ph(ph), _pp(pp) { } void operator()() { try { ByteVector buf(0x2000); size_t n; while ((n= _pp.readsome(&buf.front(), buf.size()))!=0) { fprintf(stderr, "2usb: %s\n", hexdump(&buf[0], n).c_str()); size_t total= 0; while (total < n) { size_t rn= _ph.bulkwrite(&buf.front()+total, &buf.front()+n); if (rn==size_t(-1)) { fprintf(stderr,"error writing to usb\n"); break; } total += rn; } } } catch(...) { fprintf(stderr, "EXCEPTION in copy_pipe2usb\n"); } } }; struct copy_usb2pipe { usbdev& _ph; IPCCLIENT& _pp; public: copy_usb2pipe(usbdev& ph, IPCCLIENT& pp) : _ph(ph), _pp(pp) { } void operator()() { try { ByteVector buf(0x2000); size_t n; while ((n= _ph.bulkread(buf.begin(), buf.end()))!=0) { fprintf(stderr, "2ppp: %s\n", hexdump(&buf[0], n).c_str()); if (!_pp.write(&buf.front(), n)) { fprintf(stderr,"error writing\n"); break; } } } catch(...) { fprintf(stderr, "EXCEPTION in copy_usb2pipe\n"); } } }; void handle_usbserial(usbdev& ph) { fprintf(stderr,"\nUSB Serial\n"); ph.controlread(0x21, 0x22, 0x1, 0); ph.controlread(0x21, 0x22, 0x1, 0); handle_client_server_handshake(ph); StringList args; args.push_back("115200"); // device = .1 pc = .2 args.push_back("169.254.2.2:169.254.2.1"); args.push_back("nodetach"); args.push_back("local"); // args.push_back("crtscts"); args.push_back("notty"); args.push_back("nodefaultroute"); args.push_back("noauth"); args.push_back("silent"); // wait for device to initiate connection args.push_back("debug"); args.push_back("kdebug"); args.push_back("9"); IPCCLIENT pp("/usr/sbin/pppd", args); fprintf(stderr,"start copying data\n"); boost::thread p2u(boost::ref(*new copy_pipe2usb(ph,pp))); boost::thread u2p(boost::ref(*new copy_usb2pipe(ph,pp))); fprintf(stderr,"sleep\n"); while(1) sleep(1); } struct copy_net2rndis { rndis_protocol& _ph; network_interface& _pp; copy_net2rndis(rndis_protocol& ph, network_interface& pp) : _ph(ph), _pp(pp) { } void operator()() { try { ByteVector buf(0x2000); size_t n; while ((n= _pp.readpacket(&buf.front(), buf.size()))!=0) { fprintf(stderr, "2rndis: %s\n", hexdump(&buf[0], n).c_str()); size_t total= 0; while (total < n) { size_t rn= _ph.rndis_send_packet(ByteVector(&buf.front()+total, &buf.front()+n)); if (rn==size_t(-1)) { fprintf(stderr,"error writing to rndis\n"); break; } total += rn; } } } catch(...) { fprintf(stderr, "EXCEPTION in copy_net2rndis\n"); } } }; struct copy_rndis2net { rndis_protocol& _ph; network_interface& _pp; public: copy_rndis2net(rndis_protocol& ph, network_interface& pp) : _ph(ph), _pp(pp) { } void operator()() { try { ByteVector buf(0x2000); size_t n; while ((n= _ph.rndis_read_packet(buf))!=0) { fprintf(stderr, "2net: %s\n", hexdump(&buf[0], n).c_str()); if (!_pp.sendpacket(&buf.front(), n)) { fprintf(stderr,"error writing\n"); break; } } } catch(...) { fprintf(stderr, "EXCEPTION in copy_rndis2net\n"); } } }; void handle_rndis(usbdev& ph) { fprintf(stderr, "\nRNDIS\n"); rndis_protocol rndis(ph); fprintf(stderr, "\nconnecting rndis\n"); rndis.rndis_init(); DwordVector suplist; rndis.rndis_query(rndis_protocol::OID_GEN_SUPPORTED_LIST , suplist ); printf("sup: %s\n", vhexdump(suplist).c_str()); uint16_t dvrver= rndis.rndis_query_u16(rndis_protocol::OID_GEN_VENDOR_DRIVER_VERSION ); printf("dvrver=%04x\n", dvrver); uint32_t mla = rndis.rndis_query_u32(rndis_protocol::OID_GEN_MAXIMUM_LOOKAHEAD ); printf("mla=%08x\n", mla); uint32_t macopt= rndis.rndis_query_u32(rndis_protocol::OID_GEN_MAC_OPTIONS ); printf("macopt=%08x\n", macopt); uint32_t maxpkt= rndis.rndis_query_u32(rndis_protocol::OID_GEN_MAXIMUM_SEND_PACKETS ); printf("maxpkt=%08x\n", maxpkt); uint32_t maxlst= rndis.rndis_query_u32(rndis_protocol::OID_802_3_MAXIMUM_LIST_SIZE ); printf("maxlst=%08x\n", maxlst); ByteVector curaddr(6); rndis.rndis_query(rndis_protocol::OID_802_3_CURRENT_ADDRESS , curaddr ); printf("curadr=%s\n", hexdump(curaddr).c_str()); uint32_t maxfrm= rndis.rndis_query_u32(rndis_protocol::OID_GEN_MAXIMUM_FRAME_SIZE ); printf("maxfrm=%08x\n", maxfrm); uint32_t lnkspd= rndis.rndis_query_u32(rndis_protocol::OID_GEN_LINK_SPEED ); printf("lnkspd=%08x\n", lnkspd); std::string vendor; rndis.rndis_query(rndis_protocol::OID_GEN_VENDOR_ID , vendor ); printf("vendor=%s\n", vendor.c_str()); uint32_t cnstat= rndis.rndis_query_u32(rndis_protocol::OID_GEN_MEDIA_CONNECT_STATUS ); printf("cnstat=%08x\n", cnstat); ByteVector permaddr(6); rndis.rndis_query(rndis_protocol::OID_802_3_PERMANENT_ADDRESS, permaddr ); printf("permadr=%s\n", hexdump(permaddr).c_str()); rndis.rndis_set(rndis_protocol::OID_GEN_CURRENT_LOOKAHEAD, 0x80); rndis.rndis_set(rndis_protocol::OID_GEN_CURRENT_PACKET_FILTER, 11); if (curaddr.size()!=6) { printf("ERROR getting lladdr\n"); return; } fprintf(stderr, "\ncreating network\n"); network_interface network; // fprintf(stderr, "\nsetting macaddr\n"); // network.setlladdr(curaddr); fprintf(stderr,"start copying data\n"); boost::thread p2u(boost::ref(*new copy_net2rndis(rndis,network))); boost::thread u2p(boost::ref(*new copy_rndis2net(rndis,network))); fprintf(stderr,"sleep\n"); while(1) sleep(1); // pc sends rndis init // pc queries RNDIS_OID_GEN_SUPPORTED_LIST // pc query RNDIS_OID_GEN_VENDOR_DRIVER_VERSION // pc query RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD // pc query RNDIS_OID_GEN_MAC_OPTIONS // pc query RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS // pc query RNDIS_OID_802_3_MAXIMUM_LIST_SIZE // pc query RNDIS_OID_802_3_CURRENT_ADDRESS // pc query RNDIS_OID_802_3_CURRENT_ADDRESS // pc query RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE // pc query RNDIS_OID_GEN_LINK_SPEED // pc query RNDIS_OID_GEN_MAC_OPTIONS // pc set RNDIS_OID_GEN_CURRENT_LOOKAHEAD = 0x80 // pc set RNDIS_OID_GEN_CURRENT_PACKET_FILTER = 0xb = DIRECTED|MULTICAST|BROADCAST // pc query RNDIS_OID_GEN_MEDIA_CONNECT_STATUS // first pkt from device : udp 137 // first pkt from pc : dhcp request // arp from device // udp 137 from dev // dev sends ipv6 // dhcp initiated by pc // pc: arp // pc set multicast list // pc: arp // pc query RNDIS_OID_802_3_CURRENT_ADDRESS // pc query RNDIS_OID_802_3_PERMANENT_ADDRESS // udp 137 // pc query RNDIS_OID_GEN_VENDOR_ID // pc sets RNDIS_OID_802_3_MULTICAST_LIST to 01005e000001 01005e7ffffa // pc sends tcp 1002, with ip option header: [94 04 00 00] : 'router alert' - rfcs/rfc2113.txt // udp 137 // dev sends ipv6 // pc sends ip with option // udp 137 // arp // pc sends {0x7f} to udp 5679 // pc sends to udp 137 // devce connects to tcp 990 } int main(int,char**) { try { usbdev ph; ph.support(vidpid(0xbb4,0xb51)); // startrek ph.support(vidpid(0xbb4,0xb22)); // viva advanced ph.support(vidpid(0xbb4,0xa22)); // viva no advanced ph.support(vidpid(0xbb4,0xbce)); // herald advanced ph.support(vidpid(0xbb4,0xa51)); // herald/startrek (no advanced) ph.support(vidpid(0xbb4,0xb30)); // diamond2 advanced ph.support(vidpid(0xbb4,0xa30)); // diamond2 no advanced ph.support(vidpid(0xbb4,0xb13)); // diamond rndis ph.support(vidpid(0xbb4,0xa13)); // diamond serial ph.support(vidpid(0xbb4,0xb43)); // hd mini / photon ph.support(vidpid(0xbb4,0xb0b)); // kaiser ph.support(vidpid(0x1a26,0x9d84)); // thurays sg2520 ph.support(vidpid(0xbb4,0xa51)); ph.support(vidpid(0xbb4,0xa07)); ph.support(vidpid(0x45e,0x0ce)); // >perl /Users/itsme/cvsprj/secphone/trunk/scripts/parseutlog.pl -v /Users/itsme/phones/imate-810f/updater/UTLog2.utl // >perl /Users/itsme/cvsprj/secphone/trunk/scripts/parseutlog.pl -v /Users/itsme/phones/imate-810f/updater/utlog1.utl // >perl /Users/itsme/cvsprj/secphone/trunk/scripts/parseutlog.pl -v /Users/itsme/phones/imate-810f/updater/imate.utl ph.support(vidpid(0xbb4,0x0ce)); // note: imate also has 1286:f003 while (!ph.connect()) usleep(100); fprintf(stderr,"connected\n"); ph.dumpdesc(); if (ph.isserial()) { handle_usbserial(ph); } else { handle_rndis(ph); } } catch(...) { fprintf(stderr,"EXCEPTION\n"); } } // // ep82: smb 'TOUCH_DIAMOND' on udp-137 // ep03: dhcp req from macbook // ep82: arp // // old serial usb: // perl /Users/itsme/cvsprj/secphone/trunk/scripts/parseutlog.pl -v ~/cvsprj/xda-devtools/itsutils/comm/UTLog-diamondoleg.utl // // ep81: 'CLIENT' // ep02: 'CLIENTSERVER' // ep02: 'CLIENTSERVER' // ep81: ppp setup packet //