/*ケース:切断*/ inline void case_action_dis_connect(CONNECTION_DATA* con){ REQUEST* req = &con->request; FILE* log_file; int code; USER_INFO* info = req->info; //ログオフ if((code = logoff_user(info,req->pass,req->session_id,con->ip)) != USER_LOGOFF_SUCCESS){ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Logoff Error:%d\n",info->name,code); unlock_log_file(); //KICKED connection_return_req_data_header(con,CONNECTION_ACTION_KICKED); return; } //成功 log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Logoff Success\n",info->name); unlock_log_file(); connection_return_req_data_header(con,CONNECTION_ACTION_DISCONNECT); initCrypt(&info->crypt);//この時点で暗号処理の初期化。 }
/* * If packet length > next_hop mtu, call ip_fragment */ enum IP_STATUS ip_send(const struct ppam_rx_hash *ctxt, struct annotations_t *notes, struct iphdr *ip_hdr) { BUG_ON(notes->neighbor == NULL); return ip_output(ctxt, notes, ip_hdr); }
int in_gre_output(struct mbuf *m, int af, int hlen) { struct greip *gi; gi = mtod(m, struct greip *); switch (af) { case AF_INET: /* * gre_transmit() has used M_PREPEND() that doesn't guarantee * m_data is contiguous more than hlen bytes. Use m_copydata() * here to avoid m_pullup(). */ m_copydata(m, hlen + offsetof(struct ip, ip_tos), sizeof(u_char), &gi->gi_ip.ip_tos); m_copydata(m, hlen + offsetof(struct ip, ip_id), sizeof(u_short), (caddr_t)&gi->gi_ip.ip_id); break; #ifdef INET6 case AF_INET6: gi->gi_ip.ip_tos = 0; /* XXX */ gi->gi_ip.ip_id = ip_newid(); break; #endif } gi->gi_ip.ip_ttl = V_ip_gre_ttl; gi->gi_ip.ip_len = htons(m->m_pkthdr.len); return (ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL)); }
/*-----------------------------------------------------------------------------------*/ static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) { u16_t len, tot_len; struct netif *netif; /* The TCP header has already been constructed, but the ackno and wnd fields remain. */ seg->tcphdr->ackno = htonl(pcb->rcv_nxt); /* silly window avoidance */ if(pcb->rcv_wnd < pcb->mss) { seg->tcphdr->wnd = 0; } else { seg->tcphdr->wnd = htons(pcb->rcv_wnd); } /* If we don't have a local IP address, we get one by calling ip_route(). */ if(ip_addr_isany(&(pcb->local_ip))) { netif = ip_route(&(pcb->remote_ip)); if(netif == NULL) { return; } ip_addr_set(&(pcb->local_ip), &(netif->ip_addr)); } pcb->rtime = 0; if(pcb->rttest == 0) { pcb->rttest = tcp_ticks; pcb->rtseq = ntohl(seg->tcphdr->seqno); DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %lu\n", pcb->rtseq)); } DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %lu:%lu\n", htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + seg->len)); seg->tcphdr->chksum = 0; #if CHECKSUM_GEN_TCP seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), &(pcb->remote_ip), IP_PROTO_TCP, seg->p->tot_len); #endif #ifdef TCP_STATS ++stats.tcp.xmit; #endif /* TCP_STATS */ len = seg->p->len; tot_len = seg->p->tot_len; ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL, IP_PROTO_TCP); seg->p->len = len; seg->p->tot_len = tot_len; seg->p->payload = seg->tcphdr; }
/** * Send an icmp packet in response to an incoming packet. * * @param p the input packet for which the 'unreachable' should be sent, * p->payload pointing to the IP header * @param type Type of the ICMP header * @param code Code of the ICMP header */ static void icmp_send_response(PBUF *p, uint8 type, uint8 code) { PBUF *q; IP_HDR *iphdr; /* we can use the echo header here */ ICMP_ECHO_HDR *icmphdr; /* ICMP header + IP header + 8 bytes of data */ #ifdef DBUGPBUF printf("ic:"); #endif q = pbuf_alloc(PBUF_IP, sizeof(ICMP_ECHO_HDR) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, PBUF_POOL); if (q == NULL) { return; } iphdr = p->payload; icmphdr = q->payload; icmphdr->type = type; icmphdr->code = code; icmphdr->id = 0; icmphdr->seqno = 0; /* copy fields from original packet */ SMEMCPY((uint8 *)q->payload + sizeof(ICMP_ECHO_HDR), (uint8 *)p->payload, IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); /* calculate checksum */ icmphdr->chksum = 0; icmphdr->chksum = inet_chksum(icmphdr, q->len); ip_output(q, NULL, &(iphdr->src), ICMP_TTL, 0, IP_PROTO_ICMP);printf("icmp ip_output\n"); pbuf_free(q); }
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) { struct pbuf *q; struct ip_hdr *iphdr; struct icmp_dur_hdr *idur; q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); /* ICMP header + IP header + 8 bytes of data */ iphdr = p->payload; idur = q->payload; idur->type = (char)ICMP6_DUR; idur->icode = (char)t; memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8); /* calculate checksum */ idur->chksum = 0; idur->chksum = inet_chksum(idur, q->len); #ifdef ICMP_STATS ++lwip_stats.icmp.xmit; #endif /* ICMP_STATS */ ip_output(q, NULL, (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP); pbuf_free(q); }
void tcp_rst(u32_t seqno, u32_t ackno, struct ip_addr *local_ip, struct ip_addr *remote_ip, u16_t local_port, u16_t remote_port) { struct pbuf *p; struct tcp_hdr *tcphdr; p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); if (p == NULL) { LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); return; } tcphdr = p->payload; tcphdr->src = htons(local_port); tcphdr->dest = htons(remote_port); tcphdr->seqno = htonl(seqno); tcphdr->ackno = htonl(ackno); TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK); tcphdr->wnd = htons(TCP_WND); tcphdr->urgp = 0; TCPH_HDRLEN_SET(tcphdr, 5); tcphdr->chksum = 0; #if CHECKSUM_GEN_TCP tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, IP_PROTO_TCP, p->tot_len); #endif TCP_STATS_INC(tcp.xmit); snmp_inc_tcpoutrsts(); /* Send output with hardcoded TTL since we have no access to the pcb */ ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); pbuf_free(p); LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); }
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) { struct pbuf *q; struct ip_hdr *iphdr; struct icmp_dur_hdr *idur; /* @todo: can this be PBUF_LINK instead of PBUF_IP? */ q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); /* ICMP header + IP header + 8 bytes of data */ if (q == NULL) { LWIP_DEBUGF(ICMP_DEBUG, ("icmp_dest_unreach: failed to allocate pbuf for ICMP packet.\n")); pbuf_free(p); return; } LWIP_ASSERT("check that first pbuf can hold icmp message", (q->len >= (8 + IP_HLEN + 8))); iphdr = p->payload; idur = q->payload; idur->type = (u8_t)ICMP6_DUR; idur->icode = (u8_t)t; SMEMCPY((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8); /* calculate checksum */ idur->chksum = 0; idur->chksum = inet_chksum(idur, q->len); ICMP_STATS_INC(icmp.xmit); ip_output(q, NULL, (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP); pbuf_free(q); }
/* 发送一个ICMP差错报文 */ static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code) { struct pbuf *q; struct ip_hdr *iphdr; /* we can use the echo header here */ /* 用回显请求的首部描述差错报文首部 */ struct icmp_echo_hdr *icmphdr; /* ICMP header + IP header + 8 bytes of data */ /* 在IP层申请一个pbuf,会自动预留IP首部和以太网帧首部, * 申请的大小是回显请求首部 + 引起差错的IP数据报首部大小 + IP数据报载荷的前8字节 */ q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, PBUF_RAM); if (q == NULL) { /* 申请失败,则返回 */ LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); return; } LWIP_ASSERT("check that first pbuf can hold icmp message", (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); /* 指向引起差错的IP数据报 */ iphdr = p->payload; LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); LWIP_DEBUGF(ICMP_DEBUG, (" to ")); ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); LWIP_DEBUGF(ICMP_DEBUG, ("\n")); /* 指向ICMP报文首部 */ icmphdr = q->payload; /* 填写类型字段 */ icmphdr->type = type; /* 填写代码字段 */ icmphdr->code = code; /* ICMP首部第4-7字节填0 */ icmphdr->id = 0; icmphdr->seqno = 0; /* copy fields from original packet */ /* 复制引起差错的IP数据报首部+8字节到ICMP数据字段 */ SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); /* calculate checksum */ /* 计算并填写校验和 */ icmphdr->chksum = 0; icmphdr->chksum = inet_chksum(icmphdr, q->len); ICMP_STATS_INC(icmp.xmit); /* increase number of messages attempted to send */ snmp_inc_icmpoutmsgs(); /* increase number of destination unreachable messages attempted to send */ snmp_inc_icmpouttimeexcds(); /* 调用IP层函数输出ICMP报文 */ ip_output(q, NULL, &(iphdr->src), ICMP_TTL, 0, IP_PROTO_ICMP); /* 发送完成,释放申请的ICMP用的pbuf */ pbuf_free(q); }
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) { struct pbuf *q; struct ip_hdr *iphdr; struct icmp_te_hdr *tehdr; LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n")); q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); iphdr = p->payload; tehdr = q->payload; tehdr->type = (char)ICMP6_TE; tehdr->icode = (char)t; /* copy fields from original packet */ memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8); /* calculate checksum */ tehdr->chksum = 0; tehdr->chksum = inet_chksum(tehdr, q->len); #ifdef ICMP_STATS ++lwip_stats.icmp.xmit; #endif /* ICMP_STATS */ ip_output(q, NULL, (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP); pbuf_free(q); }
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) { struct pbuf *q; struct ip_hdr *iphdr; struct icmp_dur_hdr *idur; q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); /* ICMP header + IP header + 8 bytes of data */ iphdr = p->payload; idur = q->payload; ICMPH_TYPE_SET(idur, ICMP_DUR); ICMPH_CODE_SET(idur, t); memcpy((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8); /* calculate checksum */ idur->chksum = 0; idur->chksum = inet_chksum(idur, q->len); ICMP_STATS_INC(icmp.xmit); /* increase number of messages attempted to send */ snmp_inc_icmpoutmsgs(); /* increase number of destination unreachable messages attempted to send */ snmp_inc_icmpoutdestunreachs(); ip_output(q, NULL, &(iphdr->src), ICMP_TTL, 0, IP_PROTO_ICMP); pbuf_free(q); }
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) { struct pbuf *q; struct ip_hdr *iphdr; struct icmp_te_hdr *tehdr; q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); iphdr = p->payload; LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); LWIP_DEBUGF(ICMP_DEBUG, (" to ")); ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); LWIP_DEBUGF(ICMP_DEBUG, ("\n")); tehdr = q->payload; ICMPH_TYPE_SET(tehdr, ICMP_TE); ICMPH_CODE_SET(tehdr, t); /* copy fields from original packet */ memcpy((u8_t *)q->payload + 8, (u8_t *)p->payload, IP_HLEN + 8); /* calculate checksum */ tehdr->chksum = 0; tehdr->chksum = inet_chksum(tehdr, q->len); ICMP_STATS_INC(icmp.xmit); /* increase number of messages attempted to send */ snmp_inc_icmpoutmsgs(); /* increase number of destination unreachable messages attempted to send */ snmp_inc_icmpouttimeexcds(); ip_output(q, NULL, &(iphdr->src), ICMP_TTL, 0, IP_PROTO_ICMP); pbuf_free(q); }
/*-----------------------------------------------------------------------------------*/ void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) { struct pbuf *q; struct ip_hdr *iphdr; struct icmp_te_hdr *tehdr; q = pbuf_alloc(PBUF_TRANSPORT, 8 + IP_HLEN + 8, PBUF_RAM); iphdr = p->payload; #if ICMP_DEBUG DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); ip_addr_debug_print(&(iphdr->src)); DEBUGF(ICMP_DEBUG, (" to ")); ip_addr_debug_print(&(iphdr->dest)); DEBUGF(ICMP_DEBUG, ("\n")); #endif /* ICMP_DEBNUG */ tehdr = q->payload; ICMPH_TYPE_SET(tehdr, ICMP_TE); ICMPH_CODE_SET(tehdr, t); /* copy fields from original packet */ bcopy((char *)p->payload, (char *)q->payload + 8, IP_HLEN + 8); /* calculate checksum */ tehdr->chksum = 0; tehdr->chksum = inet_chksum(tehdr, q->len); #ifdef ICMP_STATS ++stats.icmp.xmit; #endif /* ICMP_STATS */ ip_output(q, NULL, &(iphdr->src), ICMP_TTL, IP_PROTO_ICMP); pbuf_free(q); }
/*-----------------------------------------------------------------------------------*/ void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) { struct pbuf *q; struct ip_hdr *iphdr; struct icmp_dur_hdr *idur; q = pbuf_alloc(PBUF_TRANSPORT, 8 + IP_HLEN + 8, PBUF_RAM); /* ICMP header + IP header + 8 bytes of data */ iphdr = p->payload; idur = q->payload; ICMPH_TYPE_SET(idur, ICMP_DUR); ICMPH_CODE_SET(idur, t); bcopy(p->payload, (char *)q->payload + 8, IP_HLEN + 8); /* calculate checksum */ idur->chksum = 0; idur->chksum = inet_chksum(idur, q->len); #ifdef ICMP_STATS ++stats.icmp.xmit; #endif /* ICMP_STATS */ ip_output(q, NULL, &(iphdr->src), ICMP_TTL, IP_PROTO_ICMP); pbuf_free(q); }
static void udp_send_redispatch(netmsg_t msg) { struct mbuf *m = msg->send.nm_m; int pru_flags = msg->send.nm_flags; struct inpcb *inp = msg->send.base.nm_so->so_pcb; struct mbuf *m_opt = msg->send.nm_control; /* XXX save ipopt */ int flags = msg->send.nm_priv; /* ip_output flags */ int error; logudp(redisp_ipout_beg, inp); /* * - Don't use inp route cache. It should only be used in the * inp owner netisr. * - Access to inp_moptions should be safe, since multicast UDP * datagrams are redispatched to netisr0 and inp_moptions is * changed only in netisr0. */ error = ip_output(m, m_opt, NULL, flags, inp->inp_moptions, inp); if ((pru_flags & PRUS_NOREPLY) == 0) lwkt_replymsg(&msg->send.base.lmsg, error); if (m_opt != NULL) { /* Free saved ip options, if any */ m_freem(m_opt); } logudp(redisp_ipout_end, inp); }
static void icmp_echo (T_NET_BUF *input, uint_t ihoff) { T_IP4_HDR *ip4h; T_ICMP4_HDR *icmp4h; T_IN4_ADDR addr; NET_COUNT_MIB(icmp_stats.icmpInEchos, 1); /* メッセージの型をエコー要求 (8) から エコー応答 (0) に */ /* 変更して送り返す。 */ icmp4h = GET_ICMP4_HDR(input, ihoff); icmp4h->type = ICMP4_ECHO_REPLY; /* IP ヘッダの宛先と発信元を交換する。*/ ip4h = GET_IP4_HDR(input); addr = ip4h->src; ip4h->src = ip4h->dst; ip4h->dst = addr; /* チェックサムを計算する。*/ icmp4h->sum = 0; icmp4h->sum = in_cksum(icmp4h, (uint_t)(((input->len - GET_IF_IP4_HDR_SIZE(input)) + 3) >> 2 << 2)); /* 送信する。*/ NET_COUNT_ICMP4(net_count_icmp4.out_octets, input->len - GET_IF_IP4_HDR_SIZE(input)); NET_COUNT_ICMP4(net_count_icmp4.out_packets, 1); NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1); NET_COUNT_MIB(icmp_stats.icmpOutEchoReps, 1); ip_output(input, TMO_ICMP_OUTPUT); }
/*接続*/ void connection_connect(CONNECTION_DATA* con){ /*変数宣言*/ TCPsocket *sock = &con->socket; char* str; int content_length = -1; int is_err = false; FILE* log_file; /*接続先IPを取得*/ con->ip = SDLNet_TCP_GetPeerAddress(*sock); /*ビジー状態に設定*/ if(!lock_connection(con)){ SDLNet_TCP_Close(*sock); return; } /*ヘッダを判断する*/ str = NetUtl_readLine(sock); if(str == null){ /*通信終わり*/ SDLNet_TCP_Close(*sock); /*接続終了フラグ*/ unlock_connection(con); return; } if(strncmp(str,POST_HEADER,strlen(POST_HEADER)) != 0){ is_err = true; } /*とりあえず最後まで受信する。*/ if(is_err){//エラー /*ログに追加*/ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"%s\n",str); unlock_log_file(); //最後まで受信するだけ while(*(str = NetUtl_readLine(sock)) != END_CHAR){ } }else{//ヘッダを取得する while(*(str = NetUtl_readLine(sock)) != END_CHAR){ if(content_length < 0){ if(strncmp( str, CONTENT_LENGTH_HEADER, strlen(CONTENT_LENGTH_HEADER) ) == 0){ sscanf(str,CONTENT_LENGTH_HEADER_F,&content_length); } }//else if(){} } } if(!is_err && content_length >= 0){/*とりあえず通信するに値する*/ connection_do_request(con,content_length); }else{/*まったく関係ない*/ connection_send_error(sock); } /*通信終わり*/ SDLNet_TCP_Close(*sock); /*接続終了フラグ*/ unlock_connection(con); }
/** * Actually send a TCP segment over IP */ static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) { u16_t len; struct netif *netif; /* The TCP header has already been constructed, but the ackno and wnd fields remain. */ seg->tcphdr->ackno = htonl(pcb->rcv_nxt); /* silly window avoidance */ if (pcb->rcv_wnd < pcb->mss) { seg->tcphdr->wnd = 0; } else { /* advertise our receive window size in this TCP segment */ seg->tcphdr->wnd = htons(pcb->rcv_wnd); } /* If we don't have a local IP address, we get one by calling ip_route(). */ if (ip_addr_isany(&(pcb->local_ip))) { netif = ip_route(&(pcb->remote_ip)); if (netif == NULL) { return; } ip_addr_set(&(pcb->local_ip), &(netif->ip_addr)); } pcb->rtime = 0; if (pcb->rttest == 0) { pcb->rttest = tcp_ticks; pcb->rtseq = ntohl(seg->tcphdr->seqno); LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); } LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + seg->len)); len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); seg->p->len -= len; seg->p->tot_len -= len; seg->p->payload = seg->tcphdr; seg->tcphdr->chksum = 0; #if CHECKSUM_GEN_TCP seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), &(pcb->remote_ip), IP_PROTO_TCP, seg->p->tot_len); #endif TCP_STATS_INC(tcp.xmit); ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, IP_PROTO_TCP); }
int udp_output2_(struct socket *so, struct mbuf *m, const SockAddress* saddr, const SockAddress* daddr, int iptos) { register struct udpiphdr *ui; uint32_t saddr_ip = sock_address_get_ip(saddr); uint32_t daddr_ip = sock_address_get_ip(daddr); int saddr_port = sock_address_get_port(saddr); int daddr_port = sock_address_get_port(daddr); int error = 0; DEBUG_CALL("udp_output"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("m = %lx", (long)m); DEBUG_ARG("saddr = %lx", (long) saddr_ip); DEBUG_ARG("daddr = %lx", (long) daddr_ip); /* * Adjust for header */ m->m_data -= sizeof(struct udpiphdr); m->m_len += sizeof(struct udpiphdr); /* * Fill in mbuf with extended UDP header * and addresses and length put into network format. */ ui = mtod(m, struct udpiphdr *); memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr)); ui->ui_x1 = 0; ui->ui_pr = IPPROTO_UDP; ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ /* XXXXX Check for from-one-location sockets, or from-any-location sockets */ ui->ui_src = ip_seth(saddr_ip); ui->ui_dst = ip_seth(daddr_ip); ui->ui_sport = port_seth(saddr_port); ui->ui_dport = port_seth(daddr_port); ui->ui_ulen = ui->ui_len; /* * Stuff checksum and output datagram. */ ui->ui_sum = 0; if (UDPCKSUM) { if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0) ui->ui_sum = 0xffff; } ((struct ip *)ui)->ip_len = m->m_len; ((struct ip *)ui)->ip_ttl = IPDEFTTL; ((struct ip *)ui)->ip_tos = iptos; STAT(udpstat.udps_opackets++); error = ip_output(so, m); return (error); }
/* return value: < 0 : error not processed. = 0 : ok processed, packet can be released. > 0 : ok processed, packet reused, don't release. */ int icmp_echoreplay(struct ifnet * __if, struct iphdr * __ip, struct icmphdr * __icmp, int __len) { struct ifnet * ifn; struct route * rt; unsigned int tmp; // int pkt_len; int ret; ICMP_PROTO_STAT_ADD(tx_ok, 1); __icmp->type = ICMP_ECHOREPLY; /* adjust the checksum */ if (__icmp->chksum >= HTONS((0xffff - (ICMP_ECHO << 8)))) { __icmp->chksum += HTONS(ICMP_ECHO << 8) + 1; } else { __icmp->chksum += + HTONS(ICMP_ECHO << 8); } if ((rt = __route_lookup(__ip->daddr)) == NULL) { DCC_LOG1(LOG_WARNING, "no route to host: %I", __ip->daddr); ICMP_PROTO_STAT_ADD(tx_drop, 1); return -1; } ifn = (struct ifnet *)rt->rt_ifn; /* swap addresses in the ip header */ tmp = __ip->saddr; __ip->saddr = __ip->daddr; __ip->daddr = tmp; #if 0 struct iphdr * ip; pkt_len = sizeof(struct iphdr) + sizeof(struct icmphdr) + __len; ip = (struct iphdr *)ifn_mmap(ifn, pkt_len); if (ip == NULL) { return -1; } memcpy(ip, __ip, pkt_len); #endif if ((ret = ip_output(ifn, rt, __ip)) < 0) { // ifn_munmap(ifn, ip); DCC_LOG(LOG_ERROR, "ip_output() fail!"); ICMP_PROTO_STAT_ADD(tx_drop, 1); if (ret == -EAGAIN) { /* FIXME: non ethernet type interfaces */ etharp_query_pending(); } return -1; } return 1; }
/** * Output a UDP packet. * * @note This function will finally free m! */ int udp_output2(PNATState pData, struct socket *so, struct mbuf *m, struct sockaddr_in *saddr, struct sockaddr_in *daddr, int iptos) { register struct udpiphdr *ui; int error; int mlen = 0; LogFlowFunc(("ENTER: so = %R[natsock], m = %p, saddr = %RTnaipv4, daddr = %RTnaipv4\n", so, m, saddr->sin_addr.s_addr, daddr->sin_addr.s_addr)); /* in case of built-in service so might be NULL */ if (so) Assert(so->so_type == IPPROTO_UDP); /* * Adjust for header */ m->m_data -= sizeof(struct udpiphdr); m->m_len += sizeof(struct udpiphdr); mlen = m_length(m, NULL); /* * Fill in mbuf with extended UDP header * and addresses and length put into network format. */ ui = mtod(m, struct udpiphdr *); memset(ui->ui_x1, 0, 9); ui->ui_pr = IPPROTO_UDP; ui->ui_len = RT_H2N_U16((uint16_t)(mlen - sizeof(struct ip))); /* XXXXX Check for from-one-location sockets, or from-any-location sockets */ ui->ui_src = saddr->sin_addr; ui->ui_dst = daddr->sin_addr; ui->ui_sport = saddr->sin_port; ui->ui_dport = daddr->sin_port; ui->ui_ulen = ui->ui_len; /* * Stuff checksum and output datagram. */ ui->ui_sum = 0; if (udpcksum) { if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ mlen)) == 0) ui->ui_sum = 0xffff; } ((struct ip *)ui)->ip_len = mlen; ((struct ip *)ui)->ip_ttl = ip_defttl; ((struct ip *)ui)->ip_tos = iptos; udpstat.udps_opackets++; error = ip_output(pData, so, m); return error; }
void icmp_error (uint8_t code, T_NET_BUF *input) { T_IP4_HDR *ip4h; T_ICMP4_HDR *icmp4h; T_NET_BUF *output; T_IN4_ADDR saddr; uint_t len, ip4hl, align; ip4h = GET_IP4_HDR(input); ip4hl = GET_IP4_HDR_SIZE(ip4h); /* 送信用の IP データグラムを獲得する。*/ if (input->len - ip4hl < 8) len = input->len - ip4hl; else len = 8; saddr = ntohl(ip4h->src); if (in4_get_datagram(&output, (uint_t)(ICMP4_HDR_SIZE + ip4hl + len), 0, &saddr, NULL, IPPROTO_ICMP, IP4_DEFTTL, NBA_SEARCH_ASCENT, TMO_ICMP_OUTPUT) != E_OK) return; /* ICMP ヘッダを設定する。*/ icmp4h = GET_ICMP4_HDR(output, IF_IP4_ICMP4_HDR_OFFSET); icmp4h->type = ICMP4_UNREACH; icmp4h->code = code; icmp4h->data.addr= 0; /* エラーが発生した IP ヘッダと データ 8 オクテットをコピーする。*/ memcpy(GET_ICMP4_SDU(output, IF_IP4_ICMP4_HDR_OFFSET), GET_IP4_HDR(input), (size_t)(ip4hl + len)); /* 4 オクテット境界のデータ長 */ align = (len + 3) >> 2 << 2; /* 4 オクテット境界までパディングで埋める。*/ if (align > len) memset((uint8_t*)GET_ICMP4_SDU(output, IF_IP4_ICMP4_HDR_OFFSET) + ip4hl + len, 0, (size_t)(align - len)); /* チェックサムを計算する。*/ icmp4h->sum = 0; icmp4h->sum = in_cksum(icmp4h, (uint_t)(ICMP4_HDR_SIZE + ip4hl + align)); /* 送信する。*/ NET_COUNT_ICMP4(net_count_icmp4.out_octets, output->len - GET_IF_IP4_HDR_SIZE(output)); NET_COUNT_ICMP4(net_count_icmp4.out_packets, 1); NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1); NET_COUNT_MIB(icmp_stats.icmpOutDestUnreachs, 1); ip_output(output, TMO_ICMP_OUTPUT); }
int udp_output2(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr, struct sockaddr_in *daddr, int iptos) { register struct udpiphdr *ui; int error = 0; DEBUG_CALL("udp_output"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("m = %lx", (long)m); DEBUG_ARG("saddr = %lx", (long)saddr->sin_addr.s_addr); DEBUG_ARG("daddr = %lx", (long)daddr->sin_addr.s_addr); /* * Adjust for header */ m->m_data -= sizeof(struct udpiphdr); m->m_len += sizeof(struct udpiphdr); /* * Fill in mbuf with extended UDP header * and addresses and length put into network format. */ ui = mtod(m, struct udpiphdr *); ui->ui_next = ui->ui_prev = 0; ui->ui_x1 = 0; ui->ui_pr = IPPROTO_UDP; ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ /* XXXXX Check for from-one-location sockets, or from-any-location sockets */ ui->ui_src = saddr->sin_addr; ui->ui_dst = daddr->sin_addr; ui->ui_sport = saddr->sin_port; ui->ui_dport = daddr->sin_port; ui->ui_ulen = ui->ui_len; /* * Stuff checksum and output datagram. */ ui->ui_sum = 0; if (UDPCKSUM) { if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0) ui->ui_sum = 0xffff; } ((struct ip *)ui)->ip_len = m->m_len; ((struct ip *)ui)->ip_ttl = IPDEFTTL; ((struct ip *)ui)->ip_tos = iptos; STAT(udpstat.udps_opackets++); error = ip_output(so, m); return (error); }
static void igmp_sendpkt(struct in_multi *inm, int type, unsigned long addr) { struct mbuf *m; struct igmp *igmp; struct ip *ip; struct ip_moptions imo; MGETHDR(m, M_DONTWAIT, MT_HEADER); if (m == NULL) return; m->m_pkthdr.rcvif = loif; m->m_pkthdr.len = sizeof(struct ip) + IGMP_MINLEN; MH_ALIGN(m, IGMP_MINLEN + sizeof(struct ip)); m->m_data += sizeof(struct ip); m->m_len = IGMP_MINLEN; igmp = mtod(m, struct igmp *); igmp->igmp_type = type; igmp->igmp_code = 0; igmp->igmp_group = inm->inm_addr; igmp->igmp_cksum = 0; igmp->igmp_cksum = in_cksum(m, IGMP_MINLEN); m->m_data -= sizeof(struct ip); m->m_len += sizeof(struct ip); ip = mtod(m, struct ip *); ip->ip_tos = 0; ip->ip_len = sizeof(struct ip) + IGMP_MINLEN; ip->ip_off = 0; ip->ip_p = IPPROTO_IGMP; ip->ip_src.s_addr = INADDR_ANY; ip->ip_dst.s_addr = addr ? addr : igmp->igmp_group.s_addr; imo.imo_multicast_ifp = inm->inm_ifp; imo.imo_multicast_ttl = 1; imo.imo_multicast_vif = -1; /* * Request loopback of the report if we are acting as a multicast * router, so that the process-level routing demon can hear it. */ imo.imo_multicast_loop = (ip_mrouter != NULL); /* * XXX * Do we have to worry about reentrancy here? Don't think so. */ ip_output(m, router_alert, &igmprt, 0, &imo); ++igmpstat.igps_snd_reports; }
static int icmp_reflect(struct nm_if *nmif, char *inbuf, int inlen) { int hlen; struct icmp *icmp; struct ip *ip; struct in_addr t; struct inet_addr *broadaddr, *src; ip = (struct ip *)inbuf; if (IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || IN_EXPERIMENTAL(ntohl(ip->ip_src.s_addr)) || IN_ZERONET(ntohl(ip->ip_src.s_addr)) ) { pktcnt.icmp_badaddr++; return (0); } t = ip->ip_dst; ip->ip_dst = ip->ip_src; /* * If the incoming packet was addressed directly to one of our * own addresses, use dst as the src for the reply. */ if (inet_our_addr(&t) != NULL) ip->ip_src = t; else if ((broadaddr = inet_our_broadcast(&t)) != NULL) { /* * If the incoming packet was addressed to one of our broadcast * addresses, use the non-broadcast address. */ ip->ip_src = broadaddr->addr.sin_addr; } else { /* * Use the address from the interface where the ICMP packet * come in. */ src = inet_get_if_addr(nmif); if (src == NULL) return (-1); ip->ip_src = src->addr.sin_addr; } ip->ip_ttl = IPDEFTTL; hlen = ip->ip_hl << 2; icmp = (struct icmp *)(inbuf + hlen); icmp->icmp_cksum = 0; icmp->icmp_cksum = in_cksum(inbuf + hlen, inlen - hlen); return (ip_output(nmif, inbuf, inlen)); }
/** * Send an icmp packet in response to an incoming packet. * * @param p the input packet for which the 'unreachable' should be sent, * p->payload pointing to the IP header * @param type Type of the ICMP header * @param code Code of the ICMP header */ static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code) { struct pbuf *q; struct ip_hdr *iphdr; /* we can use the echo header here */ struct icmp_echo_hdr *icmphdr; /* ICMP header + IP header + 8 bytes of data */ q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, PBUF_RAM); if (q == NULL) { LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); return; } LWIP_ASSERT("check that first pbuf can hold icmp message", (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); iphdr = p->payload; LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); LWIP_DEBUGF(ICMP_DEBUG, (" to ")); ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); LWIP_DEBUGF(ICMP_DEBUG, ("\n")); icmphdr = q->payload; icmphdr->type = type; icmphdr->code = code; icmphdr->id = 0; icmphdr->seqno = 0; /* copy fields from original packet */ SMEMCPY((u8_t *) q->payload + sizeof(struct icmp_echo_hdr), (u8_t *) p->payload, IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); /* calculate checksum */ icmphdr->chksum = 0; icmphdr->chksum = inet_chksum(icmphdr, q->len); ICMP_STATS_INC(icmp.xmit); /* increase number of messages attempted to send */ snmp_inc_icmpoutmsgs(); /* increase number of destination unreachable messages attempted to send */ snmp_inc_icmpouttimeexcds(); ip_output(q, NULL, &(iphdr->src), ICMP_TTL, 0, IP_PROTO_ICMP); pbuf_free(q); }
/*-----------------------------------------------------------------------------------*/ void tcp_rst(u32_t seqno, u32_t ackno, struct ip_addr *local_ip, struct ip_addr *remote_ip, u16_t local_port, u16_t remote_port) { struct pbuf *p; struct tcp_hdr *tcphdr; p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM); if(p == NULL) { #if MEM_RECLAIM mem_reclaim(sizeof(struct pbuf)); p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM); #endif /* MEM_RECLAIM */ if(p == NULL) { DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); return; } } if(pbuf_header(p, TCP_HLEN)) { DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_send_data: no room for TCP header in pbuf.\n")); #ifdef TCP_STATS ++stats.tcp.err; #endif /* TCP_STATS */ return; } tcphdr = p->payload; tcphdr->src = htons(local_port); tcphdr->dest = htons(remote_port); tcphdr->seqno = htonl(seqno); tcphdr->ackno = htonl(ackno); TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK); tcphdr->wnd = 0; tcphdr->urgp = 0; TCPH_OFFSET_SET(tcphdr, 5 << 4); tcphdr->chksum = 0; #if CHECKSUM_GEN_TCP tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, IP_PROTO_TCP, p->tot_len); #endif #ifdef TCP_STATS ++stats.tcp.xmit; #endif /* TCP_STATS */ ip_output(p, local_ip, remote_ip, TCP_TTL, IP_PROTO_TCP); pbuf_free(p); DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %lu ackno %lu.\n", seqno, ackno)); }
/** * Send an icmp packet in response to an incoming packet. * * @param p the input packet for which the 'unreachable' should be sent, * p->payload pointing to the IP header * @param type Type of the ICMP header * @param code Code of the ICMP header */ static void ICACHE_FLASH_ATTR icmp_send_response(struct pbuf *p, u8_t type, u8_t code) { struct pbuf *q; struct ip_hdr *iphdr; /* we can use the echo header here */ struct icmp_echo_hdr *icmphdr; ip_addr_t iphdr_src; /* ICMP header + IP header + 8 bytes of data */ //为差错报文申请pbuf空间,pbuf中预留IP首部和以太网首部空间,pbuf数据区 //长度=差错报文首部+差错报文数据长度(IP首部长度+8) q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, PBUF_RAM); if (q == NULL) {//失败,返回 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); return; } LWIP_ASSERT("check that first pbuf can hold icmp message", (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); iphdr = (struct ip_hdr *)p->payload;//指向引起差错的IP数据包首部 LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); LWIP_DEBUGF(ICMP_DEBUG, (" to ")); ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); LWIP_DEBUGF(ICMP_DEBUG, ("\n")); icmphdr = (struct icmp_echo_hdr *)q->payload;//指向差错报文首部 icmphdr->type = type;//填写类型字段 icmphdr->code = code;//填写代码字段 icmphdr->id = 0;//对于目的不可达和数据报超时 icmphdr->seqno = 0;//报文,首部剩余的4个字节都为0 /* copy fields from original packet 将引起差错的IP数据报的IP首部+8字节数据拷贝到差错报文数据区*/ SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); /* calculate checksum */ icmphdr->chksum = 0;//报文校验和字段清0 icmphdr->chksum = inet_chksum(icmphdr, q->len);//计算填写校验和 ICMP_STATS_INC(icmp.xmit); /* increase number of messages attempted to send */ snmp_inc_icmpoutmsgs(); /* increase number of destination unreachable messages attempted to send */ snmp_inc_icmpouttimeexcds(); ip_addr_copy(iphdr_src, iphdr->src); ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP);//调用IP层函数输出ICMP报文 pbuf_free(q); }
/*ケース:接続*/ inline void case_action_connect(CONNECTION_DATA* con){ REQUEST* req = &con->request; FILE* log_file; int code; USER_INFO* info = req->info; //ログイン code = login_user(info,req->pass,req->session_id,con->ip); if(code == USER_LOGOFF_SUCCESS){//時間切れでログオフ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Login Error:Time out and Loggoff\n",info->name); unlock_log_file(); //KICK connection_return_req_data_header(con,CONNECTION_ACTION_DISCONNECT); initCrypt(&info->crypt);//この時点で暗号処理の初期化。 return; }else if(code != USER_LOGIN_SUCCESS){//それ以外でエラー log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Login Error:%d\n",info->name,code); unlock_log_file(); //KICK connection_return_req_data_header(con,CONNECTION_ACTION_KICKED); return; } //成功 log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Login Success\n",info->name); unlock_log_file(); connection_return_req_data_header(con,CONNECTION_ACTION_ACCEPT); //次のストリームへ nextStream(&info->crypt); }
/* routing stuff is still missing */ void tcp_respond(struct tcpiphdr *ti, IO_Rec *recs, int nr_recs, iphost_st *host_st, intf_st *ifs, tcp_seq ack, tcp_seq seq, int flags) { register int tlen=0; TRC(printf("tcp respond \n")); #define xchg(a,b,type) { type t; t=a; a=b; b=t; } xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, uint32_t); xchg(ti->ti_dport, ti->ti_sport, uint16_t); #undef xchg ti->ti_len = htons((uint16_t)(sizeof (struct tcphdr) + tlen)); tlen += sizeof (struct tcpiphdr); ti->ti_next = ti->ti_prev = 0; ti->ti_x1 = 0; TRC(printf("ack before setting back %d\n", ack)); ti->ti_seq = hton32(seq); ti->ti_ack = hton32(ack); ti->ti_x2 = 0; ti->ti_off = sizeof (struct tcphdr) >> 2; ti->ti_flags = flags; ti->ti_win = hton16(ti->ti_win); ti->ti_urp = 0; ti->ti_sum = 0; TRC(printf("calling cksum with len %d\n", tlen)); /* checksum computes over tcp and ip (overlay) header */ if (recs[1].len == 0) { ti->ti_sum = in_cksum((uint16_t *)ti, tlen); } else { printf("tcp_respond: checksum more recs, " "nr recs %d rec 0 len %d rec 1 len%d\n", nr_recs, recs[0].len, recs[1].len); ti->ti_sum = cksum_morerecs((uint16_t *)ti, recs[0].len - sizeof(struct ether_header), recs, nr_recs); } TRC(printf("calling cksum done\n")); ((struct ip *)ti)->ip_len = tlen; ((struct ip *)ti)->ip_ttl = MAXTTL; TRC(printf("tcp respond calling ip_output\n")); ip_output(recs, nr_recs, host_st, ifs, 0, flags); }