void * conn_handler(void * arr) { int client_fd = *((int*)arr); int keep_alive = 1; while (keep_alive) { http_t req; if (http_read(&req,client_fd) == -1) { http_free(&req); break; } const char * rh = http_get_status(&req); char * uri = process_http_header_request(rh); const char * conn_type = http_get_header(&req, "Connection"); if (conn_type) { if (strcasecmp("keep-alive",conn_type)) keep_alive = 0; //free(conn_type); } else { keep_alive = 0; } char * output = NULL; if (uri) { size_t size; const char * body = http_get_body(&req,&size); jsonreq_t request; request.key = NULL; request.value = NULL; parsereq(body,&request); jsonres_t response = process_request(uri,request); generateres(&output,&response,uri); if (request.key) free(request.key); if (request.value) free(request.value); //if (request) free(request); free(uri); } char * ret_str = ""; asprintf(&ret_str,"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: %zu\r\n\r\n",strlen(output)); send(client_fd,ret_str,strlen(ret_str),0); send(client_fd,output,strlen(output),0); if (output) free(output); if (ret_str) free(ret_str); http_free(&req); } free(arr); close(client_fd); return NULL; }
void nfsreq_noaddr_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2) { const struct sunrpc_msg *rp; const uint32_t *dp; nfs_type type; int v3; uint32_t proc; uint32_t access_flags; struct nfsv3_sattr sa3; ND_PRINT("%u", length); nfserr = 0; /* assume no error */ rp = (const struct sunrpc_msg *)bp; if (!xid_map_enter(ndo, rp, bp2)) /* record proc number for later on */ goto trunc; v3 = (EXTRACT_BE_U_4(&rp->rm_call.cb_vers) == NFS_VER3); proc = EXTRACT_BE_U_4(&rp->rm_call.cb_proc); if (!v3 && proc < NFS_NPROCS) proc = nfsv3_procid[proc]; ND_PRINT(" %s", tok2str(nfsproc_str, "proc-%u", proc)); switch (proc) { case NFSPROC_GETATTR: case NFSPROC_SETATTR: case NFSPROC_READLINK: case NFSPROC_FSSTAT: case NFSPROC_FSINFO: case NFSPROC_PATHCONF: if ((dp = parsereq(ndo, rp, length)) != NULL && parsefh(ndo, dp, v3) != NULL) return; break; case NFSPROC_LOOKUP: case NFSPROC_CREATE: case NFSPROC_MKDIR: case NFSPROC_REMOVE: case NFSPROC_RMDIR: if ((dp = parsereq(ndo, rp, length)) != NULL && parsefhn(ndo, dp, v3) != NULL) return; break; case NFSPROC_ACCESS: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { ND_TCHECK_4(dp); access_flags = EXTRACT_BE_U_4(dp); if (access_flags & ~NFSV3ACCESS_FULL) { /* NFSV3ACCESS definitions aren't up to date */ ND_PRINT(" %04x", access_flags); } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) { ND_PRINT(" NFS_ACCESS_FULL"); } else { char separator = ' '; if (access_flags & NFSV3ACCESS_READ) { ND_PRINT(" NFS_ACCESS_READ"); separator = '|'; } if (access_flags & NFSV3ACCESS_LOOKUP) { ND_PRINT("%cNFS_ACCESS_LOOKUP", separator); separator = '|'; } if (access_flags & NFSV3ACCESS_MODIFY) { ND_PRINT("%cNFS_ACCESS_MODIFY", separator); separator = '|'; } if (access_flags & NFSV3ACCESS_EXTEND) { ND_PRINT("%cNFS_ACCESS_EXTEND", separator); separator = '|'; } if (access_flags & NFSV3ACCESS_DELETE) { ND_PRINT("%cNFS_ACCESS_DELETE", separator); separator = '|'; } if (access_flags & NFSV3ACCESS_EXECUTE) ND_PRINT("%cNFS_ACCESS_EXECUTE", separator); } return; } break; case NFSPROC_READ: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { if (v3) { ND_TCHECK_4(dp + 2); ND_PRINT(" %u bytes @ %" PRIu64, EXTRACT_BE_U_4(dp + 2), EXTRACT_BE_U_8(dp)); } else { ND_TCHECK_4(dp + 1); ND_PRINT(" %u bytes @ %u", EXTRACT_BE_U_4(dp + 1), EXTRACT_BE_U_4(dp)); } return; } break; case NFSPROC_WRITE: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { if (v3) { ND_TCHECK_4(dp + 4); ND_PRINT(" %u (%u) bytes @ %" PRIu64, EXTRACT_BE_U_4(dp + 4), EXTRACT_BE_U_4(dp + 2), EXTRACT_BE_U_8(dp)); if (ndo->ndo_vflag) { ND_PRINT(" <%s>", tok2str(nfsv3_writemodes, NULL, EXTRACT_BE_U_4(dp + 3))); } } else { ND_TCHECK_4(dp + 3); ND_PRINT(" %u (%u) bytes @ %u (%u)", EXTRACT_BE_U_4(dp + 3), EXTRACT_BE_U_4(dp + 2), EXTRACT_BE_U_4(dp + 1), EXTRACT_BE_U_4(dp)); } return; } break; case NFSPROC_SYMLINK: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefhn(ndo, dp, v3)) != NULL) { ND_PRINT(" ->"); if (v3 && (dp = parse_sattr3(ndo, dp, &sa3)) == NULL) break; if (parsefn(ndo, dp) == NULL) break; if (v3 && ndo->ndo_vflag) print_sattr3(ndo, &sa3, ndo->ndo_vflag); return; } break; case NFSPROC_MKNOD: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefhn(ndo, dp, v3)) != NULL) { ND_TCHECK_4(dp); type = (nfs_type) EXTRACT_BE_U_4(dp); dp++; if ((dp = parse_sattr3(ndo, dp, &sa3)) == NULL) break; ND_PRINT(" %s", tok2str(type2str, "unk-ft %u", type)); if (ndo->ndo_vflag && (type == NFCHR || type == NFBLK)) { ND_TCHECK_4(dp + 1); ND_PRINT(" %u/%u", EXTRACT_BE_U_4(dp), EXTRACT_BE_U_4(dp + 1)); dp += 2; } if (ndo->ndo_vflag) print_sattr3(ndo, &sa3, ndo->ndo_vflag); return; } break; case NFSPROC_RENAME: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefhn(ndo, dp, v3)) != NULL) { ND_PRINT(" ->"); if (parsefhn(ndo, dp, v3) != NULL) return; } break; case NFSPROC_LINK: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { ND_PRINT(" ->"); if (parsefhn(ndo, dp, v3) != NULL) return; } break; case NFSPROC_READDIR: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { if (v3) { ND_TCHECK_4(dp + 4); /* * We shouldn't really try to interpret the * offset cookie here. */ ND_PRINT(" %u bytes @ %" PRId64, EXTRACT_BE_U_4(dp + 4), EXTRACT_BE_U_8(dp)); if (ndo->ndo_vflag) { /* * This displays the 8 bytes * of the verifier in order, * from the low-order byte * to the high-order byte. */ ND_PRINT(" verf %08x%08x", EXTRACT_BE_U_4(dp + 2), EXTRACT_BE_U_4(dp + 3)); } } else { ND_TCHECK_4(dp + 1); /* * Print the offset as signed, since -1 is * common, but offsets > 2^31 aren't. */ ND_PRINT(" %u bytes @ %u", EXTRACT_BE_U_4(dp + 1), EXTRACT_BE_U_4(dp)); } return; } break; case NFSPROC_READDIRPLUS: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { ND_TCHECK_4(dp + 4); /* * We don't try to interpret the offset * cookie here. */ ND_PRINT(" %u bytes @ %" PRId64, EXTRACT_BE_U_4(dp + 4), EXTRACT_BE_U_8(dp)); if (ndo->ndo_vflag) { ND_TCHECK_4(dp + 5); /* * This displays the 8 bytes * of the verifier in order, * from the low-order byte * to the high-order byte. */ ND_PRINT(" max %u verf %08x%08x", EXTRACT_BE_U_4(dp + 5), EXTRACT_BE_U_4(dp + 2), EXTRACT_BE_U_4(dp + 3)); } return; } break; case NFSPROC_COMMIT: if ((dp = parsereq(ndo, rp, length)) != NULL && (dp = parsefh(ndo, dp, v3)) != NULL) { ND_TCHECK_4(dp + 2); ND_PRINT(" %u bytes @ %" PRIu64, EXTRACT_BE_U_4(dp + 2), EXTRACT_BE_U_8(dp)); return; } break; default: return; } trunc: if (!nfserr) ND_PRINT("%s", tstr); }
void nfsreq_print_noaddr(register const u_char *bp, u_int length, register const u_char *bp2) { register const struct sunrpc_msg *rp; register const u_int32_t *dp; nfs_type type; int v3; u_int32_t proc; u_int32_t access_flags; struct nfsv3_sattr sa3; nfserr = 0; /* assume no error */ rp = (const struct sunrpc_msg *)bp; if (!xid_map_enter(rp, bp2)) /* record proc number for later on */ goto trunc; v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3); proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); if (!v3 && proc < NFS_NPROCS) proc = nfsv3_procid[proc]; switch (proc) { case NFSPROC_NOOP: printf(" nop"); return; case NFSPROC_NULL: printf(" null"); return; case NFSPROC_GETATTR: printf(" getattr"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_SETATTR: printf(" setattr"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_LOOKUP: printf(" lookup"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL) return; break; case NFSPROC_ACCESS: printf(" access"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { TCHECK(dp[0]); access_flags = EXTRACT_32BITS(&dp[0]); if (access_flags & ~NFSV3ACCESS_FULL) { /* NFSV3ACCESS definitions aren't up to date */ printf(" %04x", access_flags); } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) { printf(" NFS_ACCESS_FULL"); } else { char separator = ' '; if (access_flags & NFSV3ACCESS_READ) { printf(" NFS_ACCESS_READ"); separator = '|'; } if (access_flags & NFSV3ACCESS_LOOKUP) { printf("%cNFS_ACCESS_LOOKUP", separator); separator = '|'; } if (access_flags & NFSV3ACCESS_MODIFY) { printf("%cNFS_ACCESS_MODIFY", separator); separator = '|'; } if (access_flags & NFSV3ACCESS_EXTEND) { printf("%cNFS_ACCESS_EXTEND", separator); separator = '|'; } if (access_flags & NFSV3ACCESS_DELETE) { printf("%cNFS_ACCESS_DELETE", separator); separator = '|'; } if (access_flags & NFSV3ACCESS_EXECUTE) printf("%cNFS_ACCESS_EXECUTE", separator); } return; } break; case NFSPROC_READLINK: printf(" readlink"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_READ: printf(" read"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { if (v3) { TCHECK(dp[2]); printf(" %u bytes @ %" PRIu64, EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0])); } else { TCHECK(dp[1]); printf(" %u bytes @ %u", EXTRACT_32BITS(&dp[1]), EXTRACT_32BITS(&dp[0])); } return; } break; case NFSPROC_WRITE: printf(" write"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { if (v3) { TCHECK(dp[2]); printf(" %u (%u) bytes @ %" PRIu64, EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0])); if (vflag) { dp += 3; TCHECK(dp[0]); printf(" <%s>", tok2str(nfsv3_writemodes, NULL, EXTRACT_32BITS(dp))); } } else { TCHECK(dp[3]); printf(" %u (%u) bytes @ %u (%u)", EXTRACT_32BITS(&dp[3]), EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[1]), EXTRACT_32BITS(&dp[0])); } return; } break; case NFSPROC_CREATE: printf(" create"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL) return; break; case NFSPROC_MKDIR: printf(" mkdir"); if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp, v3) != 0) return; break; case NFSPROC_SYMLINK: printf(" symlink"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefhn(dp, v3)) != 0) { fputs(" ->", stdout); if (v3 && (dp = parse_sattr3(dp, &sa3)) == 0) break; if (parsefn(dp) == 0) break; if (v3 && vflag) print_sattr3(&sa3, vflag); return; } break; case NFSPROC_MKNOD: printf(" mknod"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefhn(dp, v3)) != 0) { TCHECK(*dp); type = (nfs_type)EXTRACT_32BITS(dp); dp++; if ((dp = parse_sattr3(dp, &sa3)) == 0) break; printf(" %s", tok2str(type2str, "unk-ft %d", type)); if (vflag && (type == NFCHR || type == NFBLK)) { TCHECK(dp[1]); printf(" %u/%u", EXTRACT_32BITS(&dp[0]), EXTRACT_32BITS(&dp[1])); dp += 2; } if (vflag) print_sattr3(&sa3, vflag); return; } break; case NFSPROC_REMOVE: printf(" remove"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL) return; break; case NFSPROC_RMDIR: printf(" rmdir"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL) return; break; case NFSPROC_RENAME: printf(" rename"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefhn(dp, v3)) != NULL) { fputs(" ->", stdout); if (parsefhn(dp, v3) != NULL) return; } break; case NFSPROC_LINK: printf(" link"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { fputs(" ->", stdout); if (parsefhn(dp, v3) != NULL) return; } break; case NFSPROC_READDIR: printf(" readdir"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { if (v3) { TCHECK(dp[4]); /* * We shouldn't really try to interpret the * offset cookie here. */ printf(" %u bytes @ %" PRId64, EXTRACT_32BITS(&dp[4]), EXTRACT_64BITS(&dp[0])); if (vflag) printf(" verf %08x%08x", dp[2], dp[3]); } else { TCHECK(dp[1]); /* * Print the offset as signed, since -1 is * common, but offsets > 2^31 aren't. */ printf(" %u bytes @ %d", EXTRACT_32BITS(&dp[1]), EXTRACT_32BITS(&dp[0])); } return; } break; case NFSPROC_READDIRPLUS: printf(" readdirplus"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { TCHECK(dp[4]); /* * We don't try to interpret the offset * cookie here. */ printf(" %u bytes @ %" PRId64, EXTRACT_32BITS(&dp[4]), EXTRACT_64BITS(&dp[0])); if (vflag) { TCHECK(dp[5]); printf(" max %u verf %08x%08x", EXTRACT_32BITS(&dp[5]), dp[2], dp[3]); } return; } break; case NFSPROC_FSSTAT: printf(" fsstat"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_FSINFO: printf(" fsinfo"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_PATHCONF: printf(" pathconf"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_COMMIT: printf(" commit"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { TCHECK(dp[2]); printf(" %u bytes @ %" PRIu64, EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0])); return; } break; default: printf(" proc-%u", EXTRACT_32BITS(&rp->rm_call.cb_proc)); return; } trunc: if (!nfserr) printf("%s", tstr); }
void nfsreq_print(register const u_char *bp, u_int length, register const u_char *bp2) { register const struct sunrpc_msg *rp; register const u_int32_t *dp; nfs_type type; int v3; u_int32_t proc; struct nfsv3_sattr sa3; char srcid[20], dstid[20]; /*fits 32bit*/ nfserr = 0; /* assume no error */ rp = (const struct sunrpc_msg *)bp; if (!nflag) { snprintf(srcid, sizeof(srcid), "%u", EXTRACT_32BITS(&rp->rm_xid)); strlcpy(dstid, "nfs", sizeof(dstid)); } else { snprintf(srcid, sizeof(srcid), "%u", EXTRACT_32BITS(&rp->rm_xid)); snprintf(dstid, sizeof(dstid), "%u", NFS_PORT); } print_nfsaddr(bp2, srcid, dstid); (void)printf("%d", length); xid_map_enter(rp, bp2); /* record proc number for later on */ v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3); proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); if (!v3 && proc < NFS_NPROCS) proc = nfsv3_procid[proc]; switch (proc) { case NFSPROC_NOOP: printf(" nop"); return; case NFSPROC_NULL: printf(" null"); return; case NFSPROC_GETATTR: printf(" getattr"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_SETATTR: printf(" setattr"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_LOOKUP: printf(" lookup"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL) return; break; case NFSPROC_ACCESS: printf(" access"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { TCHECK(dp[0]); printf(" %04x", EXTRACT_32BITS(&dp[0])); return; } break; case NFSPROC_READLINK: printf(" readlink"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_READ: printf(" read"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { if (v3) { TCHECK(dp[2]); printf(" %u bytes @ %" PRIu64, EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0])); } else { TCHECK(dp[1]); printf(" %u bytes @ %u", EXTRACT_32BITS(&dp[1]), EXTRACT_32BITS(&dp[0])); } return; } break; case NFSPROC_WRITE: printf(" write"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { if (v3) { TCHECK(dp[2]); printf(" %u (%u) bytes @ %" PRIu64, EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0])); if (vflag) { dp += 3; TCHECK(dp[0]); printf(" <%s>", tok2str(nfsv3_writemodes, NULL, EXTRACT_32BITS(dp))); } } else { TCHECK(dp[3]); printf(" %u (%u) bytes @ %u (%u)", EXTRACT_32BITS(&dp[3]), EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[1]), EXTRACT_32BITS(&dp[0])); } return; } break; case NFSPROC_CREATE: printf(" create"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL) return; break; case NFSPROC_MKDIR: printf(" mkdir"); if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp, v3) != 0) return; break; case NFSPROC_SYMLINK: printf(" symlink"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefhn(dp, v3)) != 0) { fputs(" ->", stdout); if (v3 && (dp = parse_sattr3(dp, &sa3)) == 0) break; if (parsefn(dp) == 0) break; if (v3 && vflag) print_sattr3(&sa3, vflag); return; } break; case NFSPROC_MKNOD: printf(" mknod"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefhn(dp, v3)) != 0) { TCHECK(*dp); type = (nfs_type)EXTRACT_32BITS(dp); dp++; if ((dp = parse_sattr3(dp, &sa3)) == 0) break; printf(" %s", tok2str(type2str, "unk-ft %d", type)); if (vflag && (type == NFCHR || type == NFBLK)) { TCHECK(dp[1]); printf(" %u/%u", EXTRACT_32BITS(&dp[0]), EXTRACT_32BITS(&dp[1])); dp += 2; } if (vflag) print_sattr3(&sa3, vflag); return; } break; case NFSPROC_REMOVE: printf(" remove"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL) return; break; case NFSPROC_RMDIR: printf(" rmdir"); if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL) return; break; case NFSPROC_RENAME: printf(" rename"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefhn(dp, v3)) != NULL) { fputs(" ->", stdout); if (parsefhn(dp, v3) != NULL) return; } break; case NFSPROC_LINK: printf(" link"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { fputs(" ->", stdout); if (parsefhn(dp, v3) != NULL) return; } break; case NFSPROC_READDIR: printf(" readdir"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { if (v3) { TCHECK(dp[4]); /* * We shouldn't really try to interpret the * offset cookie here. */ printf(" %u bytes @ %" PRId64, EXTRACT_32BITS(&dp[4]), EXTRACT_64BITS(&dp[0])); if (vflag) printf(" verf %08x%08x", dp[2], dp[3]); } else { TCHECK(dp[1]); /* * Print the offset as signed, since -1 is * common, but offsets > 2^31 aren't. */ printf(" %u bytes @ %d", EXTRACT_32BITS(&dp[1]), EXTRACT_32BITS(&dp[0])); } return; } break; case NFSPROC_READDIRPLUS: printf(" readdirplus"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { TCHECK(dp[4]); /* * We don't try to interpret the offset * cookie here. */ printf(" %u bytes @ %" PRId64, EXTRACT_32BITS(&dp[4]), EXTRACT_64BITS(&dp[0])); if (vflag) { TCHECK(dp[5]); printf(" max %u verf %08x%08x", EXTRACT_32BITS(&dp[5]), dp[2], dp[3]); } return; } break; case NFSPROC_FSSTAT: printf(" fsstat"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_FSINFO: printf(" fsinfo"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_PATHCONF: printf(" pathconf"); if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL) return; break; case NFSPROC_COMMIT: printf(" commit"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { TCHECK(dp[2]); printf(" %u bytes @ %" PRIu64, EXTRACT_32BITS(&dp[2]), EXTRACT_64BITS(&dp[0])); return; } break; default: printf(" proc-%u", EXTRACT_32BITS(&rp->rm_call.cb_proc)); return; } trunc: if (!nfserr) fputs(" [|nfs]", stdout); }
int main(int argc, char *argv[]) { int status, new_fd; int listensock; struct addrinfo hints, *res; struct sockaddr saddr; socklen_t saddr_size = sizeof(saddr); char buf[BUFSIZE]; int ret; struct fdnode *fdl = NULL, *writefdl = NULL, *t; struct cnode *cache = NULL; fd_set readfds, writefds; struct timeval timeout; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; if (argc != 2) { printf("Usage: %s PORT\n", argv[0]); exit(1); } if (ret = getaddrinfo(NULL, argv[1], &hints, &res)) { printf("getaddrinfo: %s\n", gai_strerror(ret)); exit(1); } if ((listensock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { perror("socket"); freeaddrinfo(res); exit(1); } if (bind(listensock, res->ai_addr, res->ai_addrlen) == -1) { perror("bind"); freeaddrinfo(res); close(listensock); exit(1); } if (listen(listensock, MAX_CON_NUM) == -1) { perror("listen"); freeaddrinfo(res); close(listensock); exit(1); } timeout.tv_sec = 60 * 3; timeout.tv_usec = 0; while (1) { struct cnode *c; int i = 0; ret = setfds(&readfds, &writefds, fdl, listensock); printf("wait for select\n"); ret = select(ret, &readfds, &writefds, NULL, &timeout); printf("got selected %d fds\n", ret); if (ret < 0) { perror("select"); break; } if (ret == 0) { /* timeout */ printf(".\n"); continue; } for (c = cache; c != NULL; c = c->next) { i++; printf("%s\n", c->url); } printf("Got %d cache pages\n", i); for (t = fdl; t != NULL; t = t->next) { if (FD_ISSET(t->fd, &readfds)) printf("%d is ready to read\n", t->fd); if (FD_ISSET(t->fd, &writefds)) printf("%d is ready to write\n", t->fd); if (FD_ISSET(t->sout, &readfds)) printf("%d is ready to read\n", t->sout); if (FD_ISSET(t->sout, &writefds)) printf("%d is ready to write\n", t->sout); } if (FD_ISSET(listensock, &readfds)) { new_fd = accept(listensock, &saddr, &saddr_size); if (new_fd == -1) { perror("accept"); continue; } ret = fdladd(new_fd, &fdl); if (ret == -1) { perror("add socket"); continue; } printf("Accepted new %d\n", new_fd); } for (t = fdl; t != NULL; t = t->next) { if (t->use && t->rw == 1 && !t->full && !t->eof && FD_ISSET(t->sout, &readfds)) { //memset(buf, 0, BUFSIZE); printf("to read from sout %d\n", t->sout); if (t->nread >= t->nwrote) { ret = read(t->sout, t->buf + t->nread, sizeof(t->buf)-t->nread); //cacheit(&cache, t->url, t->buf + t->nread, ret); if (ret == 0) { t->eof = 1; //completecache(cache, t->url); /* close(t->sout); fdlrem(t->fd, fdl); printf("Closed %d\n", t->sout); continue; */ } else { t->nread += ret; if (t->nread == sizeof(t->buf)) t->nread = 0; if (t->nread == t->nwrote) t->full = 1; t->empty = 0; } } else { ret = read(t->sout, t->buf + t->nread, t->nwrote-t->nread); //cacheit(&cache, t->url, t->buf + t->nread, ret); if (ret == 0) { t->eof = 1; //completecache(cache, t->url); /* close(t->sout); fdlrem(t->fd, fdl); printf("Closed %d\n", t->sout); continue; */ } else { t->nread += ret; if (t->nread == t->nwrote) t->full = 1; t->empty = 0; } } } if (t->use && t->rw == 0 && FD_ISSET(t->fd, &readfds)) { memset(buf, 0, BUFSIZE); printf("to read from sin %d\n", t->fd); ret = read(t->fd, buf, BUFSIZE); if (ret > 0) { int len; char *url; char *host; char *dir; write(1, buf, ret); /* Parse incoming request */ if (parsereq(buf, ret, &url, &len) == -1) { close(t->fd); close(t->sout); t->use = 0; continue; } t->url = malloc((len+1)*sizeof(char)); t->url = strncpy(t->url, url, len); t->url[len] = '\0'; /* Parse given URL */ parseurl(t->url, &len, &host, &dir); t->host = malloc((len+1)*sizeof(char)); t->host = strncpy(t->host, host, len); t->host[len] = '\0'; len = strlen(t->url) - len; t->uri = malloc((len+1)*sizeof(char)); t->uri = strncpy(t->uri, dir, len); t->uri[len] = '\0'; /* if (t->cache = cached(cache, t->url)) { t->cached = 1; t->rw = 1; continue; } */ if (ret = getaddrinfo(t->host, "http", &hints, &t->addr)) { printf("getaddrinfo: %s\n", gai_strerror(ret)); write(t->fd, "HTTP/1.0 400\r\n\r\n", 17); close(t->fd); fdlrem(t->fd, fdl); continue; } if (connect(t->sout, t->addr->ai_addr, t->addr->ai_addrlen) == -1) { if (errno == EINPROGRESS) { printf("wait for connection on %d\n", t->fd); continue; } close(t->fd); fdlrem(t->fd, fdl); } continue; } if (ret == 0) { close(t->fd); fdlrem(t->fd, fdl); printf("Closed %d\n", t->fd); } } //} /* readfds */ //for (t = fdl; t != NULL; t = t->next) { if (t->use && t->rw == 0 && FD_ISSET(t->sout, &writefds)) { int len = strlen(t->uri) + 3 + 8 + 6; char *msg = malloc(len*sizeof(char)); printf("to write to sout %d\n", t->sout); sprintf(msg, "GET %s HTTP/1.0\r\n\r\n", t->uri); if (write(t->sout, msg, len) <= 0) { perror("write sout"); close(t->fd); fdlrem(t->fd, fdl); continue; } t->rw = 1; free(msg); printf("request on %d\n", t->sout); } if (t->use && t->rw == 1 && t->cached == 0 && !t->empty && FD_ISSET(t->fd, &writefds)) { char *l; if (t->nwrote < t->nread) l = t->buf + t->nread; else l = t->buf + sizeof(t->buf); //ret = write(t->fd, t->buf + t->nwrote, l - (t->buf + t->nwrote)); ret = send(t->fd, t->buf + t->nwrote, l - (t->buf + t->nwrote), 0); if (ret <= 0) { perror("write sin"); close(t->fd); fdlrem(t->fd, fdl); continue; } t->nwrote += ret; t->full = 0; if (t->nwrote == sizeof(t->buf)) t->nwrote = 0; if (t->nwrote == t->nread) t->empty = 1; } if (t->use && t->rw == 1 && t->cached == 1 && FD_ISSET(t->fd, &writefds)) { ret = write(t->fd, t->cache->content + t->nwrote, t->cache->size - t->nwrote); t->nwrote += ret; printf("work from cache for %s\n", t->url); if (t->nwrote == t->cache->size) { t->eof = 1; t->empty = 1; } } if (t->use && t->eof && t->empty) { fdlrem(t->fd, fdl); printf("Completed %d\n", t->fd); continue; } } /* fdl traverse */ } /* while (1) */ printf("gotcha"); fdlfree(fdl); freeaddrinfo(res); close(listensock); return 0; }