📄 pptp.c
字号:
memset(pkt, 0, sizeof pkt); hnputs(pkt+0, 156); hnputs(pkt+2, 1); hnputl(pkt+4, Magic); hnputs(pkt+8, Tstart); hnputs(pkt+12, PptpProto); hnputl(pkt+16, 1); hnputl(pkt+20, 1); hnputs(pkt+24, 1); name = sysname(); if(name == nil) name = "gnot"; strcpy((char*)pkt+28, name); strcpy((char*)pkt+92, "plan 9"); if(debug) dumpctlpkt(pkt); rdexpect = Rstart; ewrite(ctlfd, pkt, 156); rpkt = recvp(rdchan); if(rpkt == nil) myfatal("recvp: %r"); if(nhgets(rpkt) != 156) myfatal("Rstart wrong length %d != 156", nhgets(rpkt)); if(rpkt[14] != 1) myfatal("Rstart error %d", rpkt[15]); free(rpkt);}voidtcallout(void){ uchar pkt[200], *rpkt; pid = getpid(); memset(pkt, 0, sizeof pkt); hnputs(pkt+0, 168); hnputs(pkt+2, 1); hnputl(pkt+4, Magic); hnputs(pkt+8, Tcallout); hnputl(pkt+16, 56000); hnputl(pkt+20, 768000); hnputl(pkt+24, 3); hnputl(pkt+28, 3); if(localwin == 0) localwin = Window; hnputs(pkt+32, localwin); if(debug) dumpctlpkt(pkt); rdexpect = Rcallout; ewrite(ctlfd, pkt, 168); rpkt = recvp(rdchan); if(rpkt == nil) myfatal("recvp: %r"); if(nhgets(rpkt) != 32) myfatal("Rcallreq wrong length %d != 32", nhgets(rpkt)); if(rpkt[16] != 1) myfatal("Rcallreq error %d", rpkt[17]); remid = nhgets(pkt+12); remwin = nhgets(pkt+24); free(rpkt);}/*voidtcallreq(void){ uchar pkt[200], *rpkt; pid = getpid(); memset(pkt, 0, sizeof pkt); hnputs(pkt+0, 220); hnputs(pkt+2, 1); hnputl(pkt+4, Magic); hnputs(pkt+8, Tcallreq); if(debug) dumpctlpkt(pkt); rdexpect = Rcallreq; ewrite(ctlfd, pkt, 220); rpkt = recvp(rdchan); if(rpkt == nil) myfatal("recvp: %r"); if(nhgets(rpkt) != 24) myfatal("Rcallreq wrong length %d != 24", nhgets(rpkt)); if(rpkt[16] != 1) myfatal("Rcallreq error %d", rpkt[17]); remid = nhgets(pkt+12); remwin = nhgets(pkt+18); free(rpkt);}voidacallcon(void){ uchar pkt[200]; memset(pkt, 0, sizeof pkt); hnputs(pkt+0, 28); hnputs(pkt+2, 1); hnputl(pkt+4, Magic); hnputs(pkt+8, Acallcon); hnputs(pkt+12, remid); if(localwin == 0) localwin = Window; hnputs(pkt+20, localwin); hnputl(pkt+24, 1); if(debug) dumpctlpkt(pkt); ewrite(ctlfd, pkt, 28);}*/intpptp(char *addr){ int p[2]; char greaddr[128]; addr = netmkaddr(addr, "net", "pptp"); ctlfd = dial(addr, nil, tcpdir, nil); if(ctlfd < 0) myfatal("dial %s: %r", addr); getaddrs(); rdchan = chancreate(sizeof(void*), 0); proccreate(pptpctlproc, nil, Stack); tstart(); tcallout(); if(pipe(p) < 0) myfatal("pipe: %r"); pppfd = p[0]; topppfd = p[1]; strcpy(greaddr, tcpdir); *strrchr(greaddr, '/') = '\0'; sprint(strrchr(greaddr, '/')+1, "gre!%I!%d", remoteip, GrePPP); print("local %I remote %I gre %s remid %d remwin %d\n", localip, remoteip, greaddr, remid, remwin); grefd = dial(greaddr, nil, nil, nil); if(grefd < 0) myfatal("dial gre: %r"); tickchan = chancreate(sizeof(int), 0); proccreate(gretimeoutproc, nil, Stack); pidchan = chancreate(sizeof(int), 0); proccreate(grereadproc, nil, Stack); recvul(pidchan); proccreate(pppreadproc, nil, Stack); recvul(pidchan); close(topppfd); return pppfd;} voidpushppp(int fd){ char *argv[16]; int argc; argc = 0; argv[argc++] = "/bin/ip/ppp"; argv[argc++] = "-C"; argv[argc++] = "-m1450"; if(debug) argv[argc++] = "-d"; if(primary) argv[argc++] = "-P"; if(pppnetmntpt){ argv[argc++] = "-x"; argv[argc++] = pppnetmntpt; } if(keyspec){ argv[argc++] = "-k"; argv[argc++] = keyspec; } argv[argc] = nil; switch(fork()){ case -1: myfatal("fork: %r"); default: return; case 0: dup(fd, 0); dup(fd, 1); exec(argv[0], argv); myfatal("exec: %r"); }}intaread(int timeout, int fd, void *buf, int nbuf){ int n; alarmed = 0; alarm(timeout); n = read(fd, buf, nbuf); alarm(0); if(alarmed) return -1; if(n < 0) myfatal("read: %r"); if(n == 0) myfatal("short read"); return n;}voidewrite(int fd, void *buf, int nbuf){ char e[ERRMAX], path[64]; if(write(fd, buf, nbuf) != nbuf){ rerrstr(e, sizeof e); strcpy(path, "unknown"); fd2path(fd, path, sizeof path); myfatal("write %d to %s: %s", nbuf, path, e); }}void*emalloc(long n){ void *v; v = malloc(n); if(v == nil) myfatal("out of memory"); return v;}intthread(void(*f)(void*), void *a){ int pid; pid=rfork(RFNOWAIT|RFMEM|RFPROC); if(pid < 0) myfatal("rfork: %r"); if(pid != 0) return pid; (*f)(a); _exits(nil); return 0; // never reaches here}voiddumpctlpkt(uchar *pkt){ fprint(2, "pkt len %d mtype %d cookie 0x%.8ux type %d\n", nhgets(pkt), nhgets(pkt+2), nhgetl(pkt+4), nhgets(pkt+8)); switch(nhgets(pkt+8)){ default: fprint(2, "\tunknown type\n"); break; case Tstart: fprint(2, "\tTstart proto %d framing %d bearer %d maxchan %d firmware %d\n", nhgets(pkt+12), nhgetl(pkt+16), nhgetl(pkt+20), nhgets(pkt+24), nhgets(pkt+26)); fprint(2, "\thost %.64s\n", (char*)pkt+28); fprint(2, "\tvendor %.64s\n", (char*)pkt+92); break; case Rstart: fprint(2, "\tRstart proto %d res %d err %d framing %d bearer %d maxchan %d firmware %d\n", nhgets(pkt+12), pkt[14], pkt[15], nhgetl(pkt+16), nhgetl(pkt+20), nhgets(pkt+24), nhgets(pkt+26)); fprint(2, "\thost %.64s\n", (char*)pkt+28); fprint(2, "\tvendor %.64s\n", (char*)pkt+92); break; case Tstop: fprint(2, "\tTstop reason %d\n", pkt[12]); break; case Rstop: fprint(2, "\tRstop res %d err %d\n", pkt[12], pkt[13]); break; case Techo: fprint(2, "\tTecho id %.8ux\n", nhgetl(pkt+12)); break; case Recho: fprint(2, "\tRecho id %.8ux res %d err %d\n", nhgetl(pkt+12), pkt[16], pkt[17]); break; case Tcallout: fprint(2, "\tTcallout id %d serno %d bps %d-%d\n", nhgets(pkt+12), nhgets(pkt+14), nhgetl(pkt+16), nhgetl(pkt+20)); fprint(2, "\tbearer 0x%x framing 0x%x recvwin %d delay %d\n", nhgetl(pkt+24), nhgetl(pkt+28), nhgets(pkt+32), nhgets(pkt+34)); fprint(2, "\tphone len %d num %.64s\n", nhgets(pkt+36), (char*)pkt+40); fprint(2, "\tsubaddr %.64s\n", (char*)pkt+104); break; case Rcallout: fprint(2, "\tRcallout id %d peerid %d res %d err %d cause %d\n", nhgets(pkt+12), nhgets(pkt+14), pkt[16], pkt[17], nhgets(pkt+18)); fprint(2, "\tconnect %d recvwin %d delay %d chan 0x%.8ux\n", nhgetl(pkt+20), nhgets(pkt+24), nhgets(pkt+26), nhgetl(pkt+28)); break; case Tcallreq: fprint(2, "\tTcallreq id %d serno %d bearer 0x%x id 0x%x\n", nhgets(pkt+12), nhgets(pkt+14), nhgetl(pkt+16), nhgetl(pkt+20)); fprint(2, "\tdialed len %d num %.64s\n", nhgets(pkt+24), (char*)pkt+28); fprint(2, "\tdialing len %d num %.64s\n", nhgets(pkt+26), (char*)pkt+92); fprint(2, "\tsubaddr %.64s\n", (char*)pkt+156); break; case Rcallreq: fprint(2, "\tRcallout id %d peerid %d res %d err %d recvwin %d delay %d\n", nhgets(pkt+12), nhgets(pkt+14), pkt[16], pkt[17], nhgets(pkt+18), nhgets(pkt+20)); break; case Acallcon: fprint(2, "\tAcallcon peerid %d connect %d recvwin %d delay %d framing 0x%x\n", nhgets(pkt+12), nhgetl(pkt+16), nhgets(pkt+20), nhgets(pkt+22), nhgetl(pkt+24)); break; case Tcallclear: fprint(2, "\tTcallclear callid %d\n", nhgets(pkt+12)); break; case Acalldis: fprint(2, "\tAcalldis callid %d res %d err %d cause %d\n", nhgets(pkt+12), pkt[14], pkt[15], nhgets(pkt+16)); fprint(2, "\tstats %.128s\n", (char*)pkt+20); break; case Awaninfo: fprint(2, "\tAwaninfo peerid %d\n", nhgets(pkt+12)); fprint(2, "\tcrc errors %d\n", nhgetl(pkt+16)); fprint(2, "\tframe errors %d\n", nhgetl(pkt+20)); fprint(2, "\thardware overruns %d\n", nhgetl(pkt+24)); fprint(2, "\tbuffer overruns %d\n", nhgetl(pkt+28)); fprint(2, "\ttime-out errors %d\n", nhgetl(pkt+32)); fprint(2, "\talignment errors %d\n", nhgetl(pkt+36)); break; case Alinkinfo: fprint(2, "\tAlinkinfo peerid %d sendaccm 0x%ux recvaccm 0x%ux\n", nhgets(pkt+12), nhgetl(pkt+16), nhgetl(pkt+20)); break; }}voidgetaddrs(void){ char buf[128]; int fd, n; sprint(buf, "%s/local", tcpdir); if((fd = open(buf, OREAD)) < 0) myfatal("could not open %s: %r", buf); if((n = read(fd, buf, sizeof(buf))) < 0) myfatal("could not read %s: %r", buf); buf[n] = 0; parseip(localip, buf); close(fd); sprint(buf, "%s/remote", tcpdir); if((fd = open(buf, OREAD)) < 0) myfatal("could not open %s: %r", buf); if((n = read(fd, buf, sizeof(buf))) < 0) myfatal("could not read %s: %r", buf); buf[n] = 0; parseip(remoteip, buf); close(fd);}voidmyfatal(char *fmt, ...){ char sbuf[512]; va_list arg; uchar buf[16]; memset(buf, 0, sizeof(buf)); hnputs(buf+0, sizeof(buf)); /* length */ hnputs(buf+2, 1); /* message type */ hnputl(buf+4, Magic); /* magic */ hnputs(buf+8, Tstop); /* op */ buf[12] = 3; /* local shutdown */ write(ctlfd, buf, sizeof(buf)); va_start(arg, fmt); vseprint(sbuf, sbuf+sizeof(sbuf), fmt, arg); va_end(arg); fprint(2, "fatal: %s\n", sbuf); threadexitsall(nil);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -