int32_t send_buf(uint8_t *buf, uint32_t len, Connection *connection, uint8_t flag, uint32_t seq_num, uint8_t *packet) { int32_t send_len = 0; uint16_t checksum = 0; /* set up the packet(seq#, crc, flag, data) */ if (len > 0) memcpy(&packet[7] , buf, len); seq_num = htonl(seq_num); memcpy(&packet[0], &seq_num, 4); packet[6] = flag; memset(&packet[4], 0, 2); checksum = in_cksum((unsigned short *)packet, len + 8); memcpy(&packet[4], &checksum, 2); if ((send_len = sendtoErr(connection->sk_num, packet, len + 8, 0, (struct sockaddr *) &(connection->remote), connection->len)) < 0) { perror("in udp send_buf, sendtoErr"); exit(-1); } return send_len; }
static int tcp_cksum(const struct ip *ip, const struct tcphdr *tp, int len) { union phu { struct phdr { u_int32_t src; u_int32_t dst; u_char mbz; u_char proto; u_int16_t len; } ph; u_int16_t pa[6]; } phu; const u_int16_t *sp; u_int32_t sum; /* pseudo-header.. */ phu.ph.len = htons((u_int16_t)len); phu.ph.mbz = 0; phu.ph.proto = IPPROTO_TCP; memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); sp = &phu.pa[0]; sum = sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]; return in_cksum((u_short *)tp, len, sum); }
static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp, u_int len) { union { struct { struct in6_addr ph_src; struct in6_addr ph_dst; u_int32_t ph_len; u_int8_t ph_zero[3]; u_int8_t ph_nxt; } ph; u_int16_t pa[20]; } phu; size_t i; u_int32_t sum = 0; /* pseudo-header */ memset(&phu, 0, sizeof(phu)); phu.ph.ph_src = ip6->ip6_src; phu.ph.ph_dst = ip6->ip6_dst; phu.ph.ph_len = htonl(len); phu.ph.ph_nxt = IPPROTO_TCP; for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) sum += phu.pa[i]; return in_cksum((u_short *)tp, len, sum); }
void srj_connect(srjconn_t *conn) { uint8_t *payload = conn->buffer + sizeof(srjhdr_t); srjhdr_t *hdr = (srjhdr_t *)conn->buffer; size_t packet_len = sizeof(srjconn_t) + 2 * sizeof(uint32_t) + sizeof(uint16_t); hdr->flag = SRJ_FLAG_FNAME; hdr->seq = 0; hdr->cksum = 0; memcpy(payload, &conn->window_size, sizeof(uint32_t)); memcpy(payload + sizeof(uint32_t), &conn->buffer_size, sizeof(uint32_t)); hdr->cksum = in_cksum((unsigned short *)conn->buffer, packet_len); sendtoErr( conn->sk, conn->buffer, packet_len, 0, (struct sockaddr *)&conn->remote, sizeof(struct sockaddr_in) ); }
char *write_icmp(char *bufferptr, unsigned short identifier) { // Grab a reference to the beggining of the header so we can come back and // calculate the checksum char *start = bufferptr; // Type (echo request) APPEND_BYTE(bufferptr, 8); // Code (zero) APPEND_BYTE(bufferptr, 0); // Zeroed checksum char *checksumstart = bufferptr; APPEND_SHORT(bufferptr, 0); // Identifier APPEND_SHORT(bufferptr, identifier); // Sequence number APPEND_SHORT(bufferptr, sequence_number); // Calculate the checksum; unsigned short checksum = in_cksum((short unsigned int *)start, ICMP_LEN); memcpy(checksumstart, &checksum, 2); return bufferptr; }
char *compareTcpChecksum(unsigned short headerChecksum, struct tcpHeader *tcpHdr, struct ipv4Header *ipHdr) { char *checksumResult = (char *) malloc(sizeof(char) * DEF_BUF_SIZE); unsigned char *tcpData = (unsigned char *) malloc( ntohs(ipHdr->totalLen) - sizeof(struct ipv4Header) + sizeof(struct tcpPseudoHeader)); unsigned short tcpPacketLength = ntohs(ipHdr->totalLen) - sizeof(struct ipv4Header); unsigned short calculatedChecksum = -1; struct tcpPseudoHeader *pseudoHdr = (struct tcpPseudoHeader *) (tcpData); pseudoHdr->zeroByte = 0x0; pseudoHdr->protocol = ipHdr->protocol; pseudoHdr->tcpLen = htons(tcpPacketLength); memcpy(pseudoHdr->srcIp, ipHdr->srcIp, IP_LENGTH); memcpy(pseudoHdr->destIp, ipHdr->destIp, IP_LENGTH); memcpy((unsigned char *)pseudoHdr + sizeof(struct tcpPseudoHeader), tcpHdr, tcpPacketLength); calculatedChecksum = in_cksum((unsigned short *) pseudoHdr, tcpPacketLength + sizeof(struct tcpPseudoHeader)); if (DEBUG) { fprintf(stdout, "given: 0x%x calculated: 0x%x\n", ntohs(headerChecksum), calculatedChecksum); } if (!calculatedChecksum) { sprintf(checksumResult, "Correct (0x%x)", ntohs(headerChecksum)); } else { sprintf(checksumResult, "Incorrect (0x%x)", ntohs(headerChecksum)); } free(tcpData); return checksumResult; }
/* (spoofed) generates and sends a (GRE) ip packet. */ void gre_spoof(unsigned int daddr,unsigned int saddr){ signed int sock=0,on=1; unsigned int psize=0; char *p,*s; struct sockaddr_in sa; struct iph ip; struct greh gre; struct sumh sum; /* create raw (GRE) socket. */ if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_GRE))<0) printe("could not allocate raw socket.",1); /* allow (on some systems) for the user-supplied ip header. */ #ifdef IP_HDRINCL if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on))) printe("could not set IP_HDRINCL socket option.",1); #endif sa.sin_family=AF_INET; sa.sin_addr.s_addr=daddr; psize=(sizeof(struct iph)+sizeof(struct greh)+sizeof(payload)-1); memset(&ip,0,sizeof(struct iph)); memset(&gre,0,sizeof(struct greh)); /* values not filled = 0, from the memset() above. */ ip.ihl=5; ip.version=4; ip.tot_len=htons(psize); ip.saddr=(saddr?saddr:random()%0xffffffff); ip.daddr=daddr; ip.ttl=(64*(random()%2+1)); ip.protocol=IPPROTO_GRE; ip.frag_off=64; /* OSI. (to isoclns_print(), then to isis_print()) */ gre.protocol=htons(254); /* needed for the ip checksum. */ sum.saddr=ip.saddr; sum.daddr=ip.daddr; sum.fill=0; sum.protocol=ip.protocol; sum.len=htons(sizeof(struct greh)+sizeof(payload)-1); /* make sum/calc buffer for the ip checksum. (correct) */ if(!(s=(char *)malloc(sizeof(struct iph)+1))) printe("malloc() failed.",1); memset(s,0,(sizeof(struct iph)+1)); memcpy(s,&ip,sizeof(struct iph)); ip.check=in_cksum((unsigned short *)s,sizeof(struct iph)); free(s); /* put the packet together. */ if(!(p=(char *)malloc(psize+1))) printe("malloc() failed.",1); memset(p,0,psize); memcpy(p,&ip,sizeof(struct iph)); memcpy(p+sizeof(struct iph),&gre,sizeof(struct greh)); memcpy(p+(sizeof(struct iph)+sizeof(struct greh)), payload,sizeof(payload)); /* send the malformed (GRE) packet. (ISIS data) */ if(sendto(sock,p,psize,0,(struct sockaddr *)&sa, sizeof(struct sockaddr))<psize) printe("failed to send forged GRE packet.",1); free(p); return; }
static int tcp_cksum(register const struct ip *ip, register const struct tcphdr *tp, register u_int len) { union phu { struct phdr { u_int32_t src; u_int32_t dst; u_char mbz; u_char proto; u_int16_t len; } ph; u_int16_t pa[6]; } phu; const u_int16_t *sp; /* pseudo-header.. */ phu.ph.len = htons((u_int16_t)len); phu.ph.mbz = 0; phu.ph.proto = IPPROTO_TCP; memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); if (IP_HL(ip) == 5) memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); else phu.ph.dst = ip_finddst(ip); sp = &phu.pa[0]; return in_cksum((u_short *)tp, len, sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]); }
/** * Copy data from a byte array in to an init packet struct. * Calculates the check sum and sticks it in the checksum location * in the header. If checksum value in the header is 0 after * unmarshalling, the packet is uncorrupted. * Malloc's and returns the init packet. **/ init_pkt_t * unmarshall_init_pkt(char * data_buff) { init_pkt_t * p_init_pkt = malloc(INIT_PKT_SZ); char * fill_buff = data_buff; /* Copy in to the header */ init_hdr_t init_hdr; memcpy(&init_hdr, fill_buff, INIT_HDR_SZ); p_init_pkt->hdr = init_hdr; /* Check filename length */ if (p_init_pkt->hdr.filename_len >= MIN_FILENAME_SZ && p_init_pkt->hdr.filename_len <= MAX_FILENAME_SZ) { /* Copy over the file name */ fill_buff = fill_buff + INIT_HDR_SZ; p_init_pkt->filename = malloc(p_init_pkt->hdr.filename_len); memcpy(p_init_pkt->filename, fill_buff, p_init_pkt->hdr.filename_len); /* Calculate the checksum */ int data_len = INIT_HDR_SZ + p_init_pkt->hdr.filename_len; u_short chk_sum = in_cksum((unsigned short *) data_buff, data_len); p_init_pkt->hdr.chk_sum = chk_sum; } else { // We know the filename length is corrupt // so we can't actually calculate the checksum // Force the checksum to be non-zero //debug_max("unmarshall_init_pkt(): problem with filename_len = %i\n", p_init_pkt->hdr.filename_len); p_init_pkt->hdr.chk_sum = 1; } print_init_pkt("unmarshall_init_pkt", p_init_pkt); return p_init_pkt; }
// 验证IP和UDP首部中的多个字段 struct udpiphdr *udp_check(char *ptr, int len) { int hlen; struct ip *ip; struct udpiphdr *ui; if (len < sizeof(struct ip) + sizeof(struct udphdr)) { err_quit("len = %d", len); } // minimal verification of IP header ip = (struct ip *) ptr; if (ip->ip_v != IPVERSION) { err_quit("ip_v = %d", ip->ip_v); } hlen = ip->ip_hl << 2; if (hlen < sizeof(struct ip)) { err_quit("ip_hl = %d", ip->ip_hl); } if (len < hlen + sizeof(struct udphdr)) { err_quit("len = %d, hlen = %d", len, hlen); } if ((ip->ip_sum = in_cksum((uint16_t *) ip, hlen)) != 0) { err_quit("ip checksum error"); } if (ip->ip_p == IPPROTO_UDP) { ui = (struct udpiphdr *) ip; return(ui); } err_quit("not a UDP packet"); return NULL; }
int32_t recv_buf(uint8_t *buf, int32_t len, int32_t recv_sk_num, Connection *from_connection, uint8_t *flag, int32_t *seq_num) { char data_buf[MAX_LEN]; int32_t recv_len = 0; uint32_t remote_len = sizeof(struct sockaddr_in); if ((recv_len = recvfrom(recv_sk_num, data_buf, len, 0, (struct sockaddr*)&(from_connection->remote), &remote_len)) < 0) { perror("in recv_buf, recvfrom"); exit(-1); } if (in_cksum((unsigned short *)data_buf, recv_len) != 0) return CRC_ERROR; *flag = data_buf[6]; memcpy(seq_num, data_buf, 4); *seq_num = ntohl(*seq_num); if (recv_len > 7) memcpy(buf, &data_buf[7], recv_len - 8); from_connection->len = remote_len; return (recv_len - 8); }
void mld_recv(int sock, void *buf, int len, struct sockaddr_storage *from, struct sockaddr_storage *to, socklen_t addrlen, unsigned int from_ifindex) { struct ip *ip; struct igmp *igmp; char ifname[IFNAMSIZ]; assert(if_indextoname(from_ifindex, ifname)); switch (from->ss_family) { case AF_INET: logger(LOG_INFO, 0, "IGMP/MLD IPv4 on %s", ifname); ip = buf; assert(ip->ip_v == 4); assert(ip->ip_hl >= 5); assert(ntohs(ip->ip_len) == len); /* TODO do we handle fragments? */ assert((ntohs(ip->ip_off) & IP_OFFMASK) == 0 && (ntohs(ip->ip_off) & (~IP_OFFMASK)) != IP_MF); assert(ip->ip_ttl == 1); assert(ip->ip_p == IPPROTO_IGMP); assert(!in_cksum(ip, ip->ip_hl << 2)); assert(IN_MULTICAST(ntohl(ip->ip_dst.s_addr))); igmp = (struct igmp *) ((char *)buf + (ip->ip_hl << 2)); assert(!in_cksum(igmp, sizeof(struct igmp))); switch (igmp->igmp_type) { default: logger(LOG_WARNING, 0, " - unknown IGMP code %d", igmp->igmp_type); } break; case AF_INET6: logger(LOG_INFO, 0, "IGMP/MLD IPv6 on %s", ifname); break; default: logger(LOG_WARNING, 0, "%s(): unknown socket type: %d", __func__, from->ss_family); } }
/* * void igmprt_membership_query() * Send a membership query on the specified interface, to the specified group. */ void igmprt_membership_query(igmp_router_t* igmprt, igmp_interface_t* ifp, struct in_addr *group, struct in_addr *sources, int numsrc, int SRSP) { char buf[12], *pbuf = NULL; igmpv2q_t *query; int size; struct sockaddr_in sin; int igmplen=0; assert(igmprt != NULL); assert(ifp != NULL); query = (igmpv2q_t *) buf; /* Set the common fields */ query->igmpq_type = IGMP_MEMBERSHIP_QUERY; query->igmpq_group.s_addr = group->s_addr; query->igmpq_cksum = 0; /* Set the version specific fields */ switch (ifp->igmpi_version) { case IGMP_VERSION_1: igmplen = 8; query->igmpq_code = 0; break; case IGMP_VERSION_2: //dbg_printf("** sending version 2 query numsrc=%d***\n",numsrc); //printf(""); igmplen = 8; query->igmpq_code = ifp->igmpi_qri; break; case IGMP_VERSION_3: printf("VERSION 3 QUERY(do not processing)getchar()\n"); getchar(); break; default: if (pbuf) free(pbuf); return; } /* Checksum */ query->igmpq_cksum = in_cksum((unsigned short*) query, igmplen); /* Send out the query */ //eddie //size=sizeof(*query)+(numsrc-1)*sizeof(struct in_addr); size=sizeof(*query); sin.sin_family = AF_INET; if (group->s_addr == 0) sin.sin_addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP); else sin.sin_addr.s_addr = group->s_addr; sendto(ifp->igmpi_socket, (void*) query, size, 0, (struct sockaddr*)&sin, sizeof(sin)); if (pbuf) free(pbuf); }
// wyślij pakiet ICMP ECHO przez gniazdo socket z ustalonym ttl void send_request(int socket, int ttl, struct RequestData* data){ data -> packet.icmp_seq = data -> seq++; // przypisz kolejny numer sekwencji data -> packet.icmp_cksum = 0; data -> packet.icmp_cksum = in_cksum((u_short*)&data -> packet, 8, 0); // policz sumę kontrolną pp_setsockopt(socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(int)); // ustaw ttl pp_sendto(socket, &data -> packet, ICMP_HEADER_LEN, 0, &data -> address, sizeof(struct sockaddr_in)); }
static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) { vec_t cksum_vec[1]; cksum_vec[0].ptr = iph; cksum_vec[0].len = ihl << 2; return in_cksum(&cksum_vec[0], 1); }
static guint16 nhrp_checksum(const guint8 *ptr, int len) { vec_t cksum_vec[1]; cksum_vec[0].ptr = ptr; cksum_vec[0].len = len; return in_cksum(&cksum_vec[0], 1); }
unsigned char ipv4_valid(unsigned char *packet, echo_request_t req, reply_response_t *res) { // Reference to where the IP section starts unsigned char *ip_start_ptr = packet; // Check if is V4 and has 20 bytes on the header char ip_version_and_header_length; CONSUME_BYTES(packet, &ip_version_and_header_length, sizeof(ip_version_and_header_length)); if (ip_version_and_header_length != 0x45) return 0; // Move forward 1 byte that represents some flags we don't care about packet += 1; // Total length of the packet CONSUME_BYTES(packet, &res->ip_packet_length, sizeof(res->ip_packet_length)); res->ip_packet_length = ntohs(res->ip_packet_length); // Move forward some bytes that represents some stuff we don't care about packet += 4; // 2 for packet ID, 2 for flags and offset // Extract ttl CONSUME_BYTES(packet, &res->ttl, sizeof(res->ttl)); // Check if the protocol is ICMP unsigned char protocol; CONSUME_BYTES(packet, &protocol, sizeof(protocol)); if (protocol != 1) return 0; // Is the checksum for the IP header correct? unsigned short checksum; unsigned char *checksum_ptr = packet; CONSUME_BYTES(packet, &checksum, sizeof(checksum)); checksum = ntohs(checksum); // Go back to the checksum start and zero it out in order to validate the message memset(checksum_ptr, 0, sizeof(checksum)); // Calculate the checksum with the info we have unsigned short calculated_checksum = in_cksum((short unsigned int *)ip_start_ptr, IP_HEADER_LEN); calculated_checksum = ntohs(calculated_checksum); if (checksum != calculated_checksum) return 0; // Source IP CONSUME_BYTES(packet, &res->source_ip, IP_ADDR_LEN * sizeof(unsigned char)); // Target IP (us) unsigned char target_ip[IP_ADDR_LEN]; CONSUME_BYTES(packet, target_ip, IP_ADDR_LEN * sizeof(unsigned char)); // Does the IP match? unsigned char i; for (i = 0; i < IP_ADDR_LEN; i++) { if (target_ip[i] != req.local_ip[i]) return 0; } return 1; }
void handleClient(struct ClientNode *client) { ssize_t bytesRcvd; uint8_t *buf = malloc(MAX_PACKET_SIZE); if (buf == NULL) { perror("handleClient:malloc"); return; } if ((bytesRcvd = recv(client->clientSocket, buf, MAX_PACKET_SIZE-1, 0)) < 0) { perror("handleClient:recv"); free(buf); return; } // Check for a shutdown if (bytesRcvd == 0) { removeClient(client); } // Parse the buffer else { client->packetLength = bytesRcvd; client->packetData = (struct ChatHeader *)buf; // make sure the checksum is correct before parsing the packets if (in_cksum((uint16_t *)client->packetData, client->packetLength) == 0) { // Put the packet header fields in host order switch (client->packetData->flag) { case FLAG_INIT_REQ: registerHandle(client); break; case FLAG_MSG_REQ: case FLAG_MSG_ACK: forwardMessage(client); break; case FLAG_EXIT_REQ: clientExit(client); break; case FLAG_LIST_REQ: getClientCount(client); break; case FLAG_HNDL_REQ: clientNameRequest(client); break; case FLAG_INIT_ACK: case FLAG_INIT_ERR: case FLAG_MSG_ERR: case FLAG_EXIT_ACK: case FLAG_LIST_RESP: case FLAG_HNDL_RESP: default: break; } } client->packetData = NULL; client->packetLength = 0; } free(buf); }
void make_cpkt(CPacket* controlPacket, unsigned char type, int seq){ controlPacket->header.type = type; // ACK or END controlPacket->header.seq = seq%256; controlPacket->header.len = HEADER_LEN; controlPacket->header.checksum = in_cksum((uint16_t *)controlPacket , controlPacket->header.len); return 0; }
/* * Function : udpf_send_pkt_through_socket * Responsiblity : To send a unicast packet to a known server address. * Parameters : pkt - IP packet * size - size of udp payload * in_pktinfo - pktInfo * to - it has destination address and port number * Returns: true - packet is sent successfully. * false - any failures. */ static bool udpfwd_send_pkt_through_socket(void *pkt, int32_t size, struct in_pktinfo *pktInfo, struct sockaddr_in* to) { struct msghdr msg; struct iovec iov[1]; struct cmsghdr *cmptr; struct in_pktinfo p = *pktInfo; struct ip *iph; struct udphdr *udph; union control_u ctrl; char result = false; /* Update IP and UDP header checksum fields */ iph = (struct ip *) pkt; udph = (struct udphdr *) ((char *)iph + (iph->ip_hl * 4)); /* Set destination ip and udp port number in the packet */ iph->ip_dst.s_addr = to->sin_addr.s_addr; udph->uh_dport = to->sin_port; iph->ip_sum = in_cksum((uint16_t *) pkt, iph->ip_len, 0); /* FIXME: Add udp checksum calculation function */ udph->check = 0; iov[0].iov_base = pkt; iov[0].iov_len = size; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; msg.msg_name = to; msg.msg_namelen = sizeof(struct sockaddr_in); msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = &ctrl; msg.msg_controllen = sizeof(union control_u); cmptr = CMSG_FIRSTHDR(&msg); memcpy(CMSG_DATA(cmptr), &p, sizeof(p)); msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); cmptr->cmsg_level = IPPROTO_IP; cmptr->cmsg_type = IP_PKTINFO; assert(udpfwd_ctrl_cb_p->udpSockFd); if (sendmsg(udpfwd_ctrl_cb_p->udpSockFd, &msg, 0) < 0 ) { VLOG_ERR("errno = %d, sending packet failed", errno); } else { result = true; } return result; }
/* * IPsec input callback for INET protocols. * This routine is called as the transform callback. * Takes care of filtering and other sanity checks on * the processed packet. */ int ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int protoff) { char buf[INET6_ADDRSTRLEN]; struct ipsec_ctx_data ctx; int prot, af, sproto, isr_prot; struct ip *ip; struct m_tag *mtag; struct tdb_ident *tdbi; struct secasindex *saidx; int error; #ifdef INET6 #ifdef notyet char ip6buf[INET6_ADDRSTRLEN]; #endif #endif IPSEC_ASSERT(m != NULL, ("null mbuf")); IPSEC_ASSERT(sav != NULL, ("null SA")); IPSEC_ASSERT(sav->sah != NULL, ("null SAH")); saidx = &sav->sah->saidx; af = saidx->dst.sa.sa_family; IPSEC_ASSERT(af == AF_INET, ("unexpected af %u", af)); sproto = saidx->proto; IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH || sproto == IPPROTO_IPCOMP, ("unexpected security protocol %u", sproto)); /* Sanity check */ if (m == NULL) { DPRINTF(("%s: null mbuf", __func__)); IPSEC_ISTAT(sproto, badkcr); KEY_FREESAV(&sav); return EINVAL; } if (skip != 0) { /* * Fix IPv4 header * XXXGL: do we need this entire block? */ if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) { DPRINTF(("%s: processing failed for SA %s/%08lx\n", __func__, ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), (u_long) ntohl(sav->spi))); IPSEC_ISTAT(sproto, hdrops); error = ENOBUFS; goto bad; } ip = mtod(m, struct ip *); ip->ip_len = htons(m->m_pkthdr.len); ip->ip_sum = 0; ip->ip_sum = in_cksum(m, ip->ip_hl << 2); } else {
struct packet ackpkt(const struct packet *src) { struct packet ret = { 0 }; if (src != NULL) { memcpy(&ret, src, sizeof(*src)); ret.type = PKT_TYPE_RR; ret.checksum = 0; ret.checksum = in_cksum((unsigned short *)&ret, sizeof(ret)); memset(ret.data, PKT_TYPE_RR, }
unsigned short calculate_ip_sum(mapipacket *p) { unsigned int sum; int ip_hl; p->iph->ip_csum = 0; ip_hl = IP2_HLEN(p->iph) << 2; sum = in_cksum((u_int16_t *)p->iph, ip_hl); return (unsigned short)(CKSUM_CARRY(sum)); }
void vrrp_print(register const u_char *bp, register u_int len, int ttl) { int version, type, auth_type; const char *type_s; TCHECK(bp[0]); version = (bp[0] & 0xf0) >> 4; type = bp[0] & 0x0f; type_s = tok2str(type2str, "unknown type (%u)", type); printf("VRRPv%u, %s", version, type_s); if (ttl != 255) printf(", (ttl %u)", ttl); if (version != 2 || type != VRRP_TYPE_ADVERTISEMENT) return; TCHECK(bp[2]); printf(", vrid %u, prio %u", bp[1], bp[2]); TCHECK(bp[5]); auth_type = bp[4]; printf(", authtype %s", tok2str(auth2str, NULL, auth_type)); printf(", intvl %us, length %u", bp[5],len); if (vflag) { int naddrs = bp[3]; int i; char c; if (TTEST2(bp[0], len) && in_cksum((const u_short*)bp, len, 0)) printf(", (bad vrrp cksum %x)", EXTRACT_16BITS(&bp[6])); printf(", addrs"); if (naddrs > 1) printf("(%d)", naddrs); printf(":"); c = ' '; bp += 8; for (i = 0; i < naddrs; i++) { TCHECK(bp[3]); printf("%c%s", c, ipaddr_string(bp)); c = ','; bp += 4; } if (auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */ TCHECK(bp[7]); printf(" auth \""); if (fn_printn(bp, 8, snapend)) { printf("\""); goto trunc; } printf("\""); } } return; trunc: printf("[|vrrp]"); }
void main(int argc, char **argv) { int sock, i, ctr, k; int on = 1; struct sockaddr_in addrs; if (argc < 3) { printf("Usage: %s <ip_addr> <port>\n", argv[0]); exit(-1); } for (i = 0; i < 1002; i++) { icmph.text[i] = random() % 255; } sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) == -1) { perror("Can't set IP_HDRINCL option on socket"); } if (sock < 0) { exit(-1); } fflush(stdout); for (ctr = 0;ctr < 1001;ctr++) { ctr = ctr % 1000; addrs = sock_open(argv[1], sock, atoi(argv[2])); icmph.iph.version = 4; icmph.iph.ihl = 6; icmph.iph.tot_len = 1024; icmph.iph.id = htons(0x001); icmph.iph.ttl = 255; icmph.iph.protocol = IPPROTO_ICMP; icmph.iph.saddr = ((random() % 255) * 255 * 255 * 255) + ((random() % 255) * 65535) + ((random() % 255) * 255) + (random() % 255); icmph.iph.daddr = addrs.sin_addr.s_addr; icmph.iph.frag_off = htons(0); icmph.icp.icmp_type = random() % 14; icmph.icp.icmp_code = random() % 10; icmph.icp.icmp_cksum = 0; icmph.icp.icmp_id = 2650; icmph.icp.icmp_seq = random() % 255; icmph.icp.icmp_cksum = in_cksum((int *)&icmph.icp, 1024); if (sendto(sock, &icmph, 1024, 0, (struct sockaddr *)&addrs,sizeof(struct sockaddr)) == -1) { if (errno != ENOBUFS) printf("X"); } if (ctr == 0) printf("b00m "); fflush(stdout); } close(sock); }
int send_to_next_node(struct tour_packet *packet,int nodes) { struct ip *ip_hdr ; ip_hdr = (struct ip *)&(packet->ip_header); struct sockaddr_in *destnode = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); uint32_t src_addr = host_ip_struct.s_addr; destnode->sin_family = AF_INET; packet->index++; struct in_addr addr_test; addr_test.s_addr = packet->vm_list[packet->index].s_addr; while (getVMbyIPaddr(addr_test) == NULL) { printf("\n Next address not retreivable from Tour \n"); if (packet->index == packet->end_index) { printf("\n Since address not accessible from packet, Ending Tour \n"); tour_ended = 1; return 1; } packet->index++; } destnode->sin_addr.s_addr = packet->vm_list[packet->index].s_addr; int size = sizeof(struct tour_packet); //calculate check sum uint16_t ck_sum = in_cksum((uint16_t *)packet,size); ip_hdr->ip_hl = sizeof(struct ip) >> 2; ip_hdr->ip_v = IPVERSION; ip_hdr->ip_tos = 0; ip_hdr->ip_len = htons(size); ip_hdr->ip_id = htons(ID); ip_hdr->ip_off = 0; ip_hdr->ip_ttl = TTL_VAL; ip_hdr->ip_p = PROTO_ID; ip_hdr->ip_src.s_addr = src_addr; ip_hdr->ip_dst.s_addr = packet->vm_list[packet->index].s_addr; ip_hdr->ip_sum = ck_sum; int len = sizeof(struct tour_packet); int s = sendto(rt_fd,packet,size,0,(struct sockaddr *)destnode,sizeof(struct sockaddr)); //printf("send outputs %d \n",s); if (s<=0){ perror("send error"); } char *ipaddr = Sock_ntop_host((struct sockaddr *)destnode, sizeof(struct sockaddr)); char vmip[INET_ADDRSTRLEN]; char src_ip[INET_ADDRSTRLEN]; struct in_addr des; des.s_addr = ip_hdr->ip_dst.s_addr; inet_ntop(AF_INET,&des,vmip,INET_ADDRSTRLEN); printf("\n Sending Tour socket %s dest %s src address is %s \n",ipaddr,vmip,inet_ntop(AF_INET,&ip_hdr->ip_src,src_ip,INET_ADDRSTRLEN)); return size; }
int fill_ping_packet_header(struct ping_packet *p_packet,uint32_t src_ip,uint32_t dst_ip) { int len; struct icmp *icmp_hdr; static int nsent = 1; memcpy(p_packet->dest_mac,dst_mac,MACLEN); memcpy(p_packet->src_mac, src_mac,MACLEN); p_packet->proto_id = htons(ETH_P_IP); icmp_hdr = &(p_packet->ping_hdr.icmp_hdr); icmp_hdr->icmp_type = ICMP_ECHO; icmp_hdr->icmp_code = 0; icmp_hdr->icmp_id = htons(PING_ID); icmp_hdr->icmp_seq = htons(++nsent); //memset(icmp_hdr->icmp_data, 0xa5, 56); Gettimeofday((struct timeval *) icmp_hdr->icmp_data, NULL); //len = 8 + datalen; len = sizeof(struct icmp); icmp_hdr->icmp_cksum = 0; icmp_hdr->icmp_cksum = in_cksum((uint16_t *) icmp_hdr, len); struct ip *ip_hdr ; ip_hdr = (struct ip*)&(p_packet->ping_hdr.ip_hdr); ip_hdr->ip_hl = sizeof(struct ip) >> 2; ip_hdr->ip_v = IPVERSION; ip_hdr->ip_tos = 0; ip_hdr->ip_len = htons(sizeof(struct ping_header)); ip_hdr->ip_id = htons(PING_ID); ip_hdr->ip_off = 0; ip_hdr->ip_ttl = 64; ip_hdr->ip_p = IPPROTO_ICMP; ip_hdr->ip_src.s_addr = src_ip; ip_hdr->ip_dst.s_addr = dst_ip; int size = sizeof(struct ip); ip_hdr->ip_sum = in_cksum((uint16_t *)ip_hdr,size); return 1; }
struct packet retransmitpkt(uint32_t sequence) { struct packet ret = { 0 }; ret.type = PKT_TYPE_REJ; ret.sequence = htonl(sequence); ret.size = 0; memset(ret.data, PKT_TYPE_REJ, PKT_DMAX); ret.checksum = in_cksum((unsigned short *)&ret, sizeof(ret)); return ret; }
/* * RFC 2338: * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Auth Type | Adver Int | Checksum | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IP Address (1) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | . | * | . | * | . | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IP Address (n) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Authentication Data (1) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Authentication Data (2) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ void vrrp_print(register const u_char *bp, register u_int len, int ttl) { int version, type, auth_type; char *type_s; TCHECK(bp[0]); version = (bp[0] & 0xf0) >> 4; type = bp[0] & 0x0f; if (type == 1) type_s = "advertise"; else type_s = "unknown"; printf("VRRPv%d-%s %d: ", version, type_s, len); if (ttl != 255) printf("[ttl=%d!] ", ttl); if (version != 2 || type != 1) return; TCHECK(bp[2]); printf("vrid=%d prio=%d", bp[1], bp[2]); TCHECK(bp[5]); auth_type = bp[4]; if (auth_type != 0) printf(" authtype=%d", auth_type); printf(" intvl=%d", bp[5]); if (vflag) { int naddrs = bp[3]; int i; char c; if (TTEST2(bp[0], len) && in_cksum((const u_short*)bp, len, 0)) printf(" (bad vrrp cksum %x!)", EXTRACT_16BITS(&bp[6])); printf(" addrs"); if (naddrs > 1) printf("(%d)", naddrs); printf(":"); c = ' '; bp += 8; for (i = 0; i < naddrs; i++) { TCHECK(bp[3]); printf("%c%s", c, ipaddr_string(bp)); c = ','; bp += 4; } if (auth_type == 1) { /* simple text password */ TCHECK(bp[7]); printf(" auth %.8s", bp); } } return; trunc: printf("[|vrrp]"); }
static int ipfw_divert(struct mbuf **m, int incoming, int tee) { /* * ipfw_chk() has already tagged the packet with the divert tag. * If tee is set, copy packet and return original. * If not tee, consume packet and send it to divert socket. */ #ifdef IPDIVERT struct mbuf *clone, *reass; struct ip *ip; int hlen; reass = NULL; /* Cloning needed for tee? */ if (tee) clone = m_dup(*m, M_DONTWAIT); else clone = *m; /* In case m_dup was unable to allocate mbufs. */ if (clone == NULL) goto teeout; /* * Divert listeners can only handle non-fragmented packets. * However when tee is set we will *not* de-fragment the packets; * Doing do would put the reassembly into double-jeopardy. On top * of that someone doing a tee will probably want to get the packet * in its original form. */ ip = mtod(clone, struct ip *); if (!tee && ip->ip_off & (IP_MF | IP_OFFMASK)) { /* Reassemble packet. */ reass = ip_reass(clone); /* * IP header checksum fixup after reassembly and leave header * in network byte order. */ if (reass != NULL) { ip = mtod(reass, struct ip *); hlen = ip->ip_hl << 2; ip->ip_len = htons(ip->ip_len); ip->ip_off = htons(ip->ip_off); ip->ip_sum = 0; if (hlen == sizeof(struct ip)) ip->ip_sum = in_cksum_hdr(ip); else ip->ip_sum = in_cksum(reass, hlen); clone = reass; } else