📄 common.c
字号:
sum += (UINT32_t) tmp; addr += sizeof(tmp); count -= sizeof(tmp); } if (count > 0) { sum += (unsigned char) *addr; } while(sum >> 16) { sum = (sum & 0xffff) + (sum >> 16); } return (UINT16_t) ((~sum) & 0xFFFF);}/***********************************************************************%FUNCTION: clampMSS*%ARGUMENTS:* packet -- PPPoE session packet* dir -- either "incoming" or "outgoing"* clampMss -- clamp value*%RETURNS:* Nothing*%DESCRIPTION:* Clamps MSS option if TCP SYN flag is set.***********************************************************************/voidclampMSS(PPPoEPacket *packet, char const *dir, int clampMss){ unsigned char *tcpHdr; unsigned char *ipHdr; unsigned char *opt; unsigned char *endHdr; unsigned char *mssopt = NULL; UINT16_t csum; int len, minlen; /* check PPP protocol type */ if (packet->payload[0] & 0x01) { /* 8 bit protocol type */ /* Is it IPv4? */ if (packet->payload[0] != 0x21) { /* Nope, ignore it */ return; } ipHdr = packet->payload + 1; minlen = 41; } else { /* 16 bit protocol type */ /* Is it IPv4? */ if (packet->payload[0] != 0x00 || packet->payload[1] != 0x21) { /* Nope, ignore it */ return; } ipHdr = packet->payload + 2; minlen = 42; } /* Is it too short? */ len = (int) ntohs(packet->length); if (len < minlen) { /* 20 byte IP header; 20 byte TCP header; at least 1 or 2 byte PPP protocol */ return; } /* Verify once more that it's IPv4 */ if ((ipHdr[0] & 0xF0) != 0x40) { return; } /* Is it a fragment that's not at the beginning of the packet? */ if ((ipHdr[6] & 0x1F) || ipHdr[7]) { /* Yup, don't touch! */ return; } /* Is it TCP? */ if (ipHdr[9] != 0x06) { return; } /* Get start of TCP header */ tcpHdr = ipHdr + (ipHdr[0] & 0x0F) * 4; /* Is SYN set? */ if (!(tcpHdr[13] & 0x02)) { return; } /* Compute and verify TCP checksum -- do not touch a packet with a bad checksum */ csum = computeTCPChecksum(ipHdr, tcpHdr); if (csum) { syslog(LOG_ERR, "Bad TCP checksum %x", (unsigned int) csum); /* Upper layers will drop it */ return; } /* Look for existing MSS option */ endHdr = tcpHdr + ((tcpHdr[12] & 0xF0) >> 2); opt = tcpHdr + 20; while (opt < endHdr) { if (!*opt) break; /* End of options */ switch(*opt) { case 1: opt++; break; case 2: if (opt[1] != 4) { /* Something fishy about MSS option length. */ syslog(LOG_ERR, "Bogus length for MSS option (%u) from %u.%u.%u.%u", (unsigned int) opt[1], (unsigned int) ipHdr[12], (unsigned int) ipHdr[13], (unsigned int) ipHdr[14], (unsigned int) ipHdr[15]); return; } mssopt = opt; break; default: if (opt[1] < 2) { /* Someone's trying to attack us? */ syslog(LOG_ERR, "Bogus TCP option length (%u) from %u.%u.%u.%u", (unsigned int) opt[1], (unsigned int) ipHdr[12], (unsigned int) ipHdr[13], (unsigned int) ipHdr[14], (unsigned int) ipHdr[15]); return; } opt += (opt[1]); break; } /* Found existing MSS option? */ if (mssopt) break; } /* If MSS exists and it's low enough, do nothing */ if (mssopt) { unsigned mss = mssopt[2] * 256 + mssopt[3]; if (mss <= clampMss) { return; } mssopt[2] = (((unsigned) clampMss) >> 8) & 0xFF; mssopt[3] = ((unsigned) clampMss) & 0xFF; } else { /* No MSS option. Don't add one; we'll have to use 536. */ return; } /* Recompute TCP checksum */ tcpHdr[16] = 0; tcpHdr[17] = 0; csum = computeTCPChecksum(ipHdr, tcpHdr); (* (UINT16_t *) (tcpHdr+16)) = csum;}/************************************************************************%FUNCTION: sendPADT*%ARGUMENTS:* conn -- PPPoE connection* msg -- if non-NULL, extra error message to include in PADT packet.*%RETURNS:* Nothing*%DESCRIPTION:* Sends a PADT packet***********************************************************************/voidsendPADT(PPPoEConnection *conn, char const *msg){ PPPoEPacket packet; unsigned char *cursor = packet.payload; UINT16_t plen = 0; /* Do nothing if no session established yet */ if (!conn->session) return; /* Do nothing if no discovery socket */ if (conn->discoverySocket < 0) return; memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN); memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); packet.ver = 1; packet.type = 1; packet.code = CODE_PADT; packet.session = conn->session; /* Reset Session to zero so there is no possibility of recursive calls to this function by any signal handler */ conn->session = 0; /* If we're using Host-Uniq, copy it over */ if (conn->useHostUniq) { PPPoETag hostUniq; pid_t pid = getpid(); hostUniq.type = htons(TAG_HOST_UNIQ); hostUniq.length = htons(sizeof(pid)); memcpy(hostUniq.payload, &pid, sizeof(pid)); memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); cursor += sizeof(pid) + TAG_HDR_SIZE; plen += sizeof(pid) + TAG_HDR_SIZE; } /* Copy error message */ if (msg) { PPPoETag err; size_t elen = strlen(msg); err.type = htons(TAG_GENERIC_ERROR); err.length = htons(elen); strcpy((char *) err.payload, msg); memcpy(cursor, &err, elen + TAG_HDR_SIZE); cursor += elen + TAG_HDR_SIZE; plen += elen + TAG_HDR_SIZE; } /* Copy cookie and relay-ID if needed */ if (conn->cookie.type) { CHECK_ROOM(cursor, packet.payload, ntohs(conn->cookie.length) + TAG_HDR_SIZE); memcpy(cursor, &conn->cookie, ntohs(conn->cookie.length) + TAG_HDR_SIZE); cursor += ntohs(conn->cookie.length) + TAG_HDR_SIZE; plen += ntohs(conn->cookie.length) + TAG_HDR_SIZE; } if (conn->relayId.type) { CHECK_ROOM(cursor, packet.payload, ntohs(conn->relayId.length) + TAG_HDR_SIZE); memcpy(cursor, &conn->relayId, ntohs(conn->relayId.length) + TAG_HDR_SIZE); cursor += ntohs(conn->relayId.length) + TAG_HDR_SIZE; plen += ntohs(conn->relayId.length) + TAG_HDR_SIZE; } packet.length = htons(plen); sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); if (conn->debugFile) { dumpPacket(conn->debugFile, &packet, "SENT"); fprintf(conn->debugFile, "\n"); fflush(conn->debugFile); } syslog(LOG_INFO,"Sent PADT");}/************************************************************************%FUNCTION: sendPADTf*%ARGUMENTS:* conn -- PPPoE connection* msg -- printf-style format string* args -- arguments for msg*%RETURNS:* Nothing*%DESCRIPTION:* Sends a PADT packet with a formatted message***********************************************************************/voidsendPADTf(PPPoEConnection *conn, char const *fmt, ...){ char msg[512]; va_list ap; va_start(ap, fmt); vsnprintf(msg, sizeof(msg), fmt, ap); va_end(ap); msg[511] = 0; sendPADT(conn, msg);}/***********************************************************************%FUNCTION: parseLogErrs*%ARGUMENTS:* type -- tag type* len -- tag length* data -- tag data* extra -- extra user data*%RETURNS:* Nothing*%DESCRIPTION:* Picks error tags out of a packet and logs them.***********************************************************************/voidparseLogErrs(UINT16_t type, UINT16_t len, unsigned char *data, void *extra){ switch(type) { case TAG_SERVICE_NAME_ERROR: syslog(LOG_ERR, "PADT: Service-Name-Error: %.*s", (int) len, data); fprintf(stderr, "PADT: Service-Name-Error: %.*s\n", (int) len, data); break; case TAG_AC_SYSTEM_ERROR: syslog(LOG_ERR, "PADT: System-Error: %.*s", (int) len, data); fprintf(stderr, "PADT: System-Error: %.*s\n", (int) len, data); break; case TAG_GENERIC_ERROR: syslog(LOG_ERR, "PADT: Generic-Error: %.*s", (int) len, data); fprintf(stderr, "PADT: Generic-Error: %.*s\n", (int) len, data); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -