| 915 | } |
| 916 | |
| 917 | static void |
| 918 | TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int sndrply, int direction) |
| 919 | { |
| 920 | int sctp_size = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_error_cause); |
| 921 | int ip_size = sizeof(struct ip) + sctp_size; |
| 922 | int include_error_cause = 1; |
| 923 | char tmp_ip[ip_size]; |
| 924 | char addrbuf[INET_ADDRSTRLEN]; |
| 925 | |
| 926 | if (ntohs(sm->ip_hdr->ip_len) < ip_size) { /* short packet, cannot send error cause */ |
| 927 | include_error_cause = 0; |
| 928 | ip_size = ip_size - sizeof(struct sctp_error_cause); |
| 929 | sctp_size = sctp_size - sizeof(struct sctp_error_cause); |
| 930 | } |
| 931 | /* Assign header pointers packet */ |
| 932 | struct ip* ip = (struct ip *) tmp_ip; |
| 933 | struct sctphdr* sctp_hdr = (struct sctphdr *) ((char *) ip + sizeof(*ip)); |
| 934 | struct sctp_chunkhdr* chunk_hdr = (struct sctp_chunkhdr *) ((char *) sctp_hdr + sizeof(*sctp_hdr)); |
| 935 | struct sctp_error_cause* error_cause = (struct sctp_error_cause *) ((char *) chunk_hdr + sizeof(*chunk_hdr)); |
| 936 | |
| 937 | /* construct ip header */ |
| 938 | ip->ip_v = sm->ip_hdr->ip_v; |
| 939 | ip->ip_hl = 5; /* 5*32 bit words */ |
| 940 | ip->ip_tos = 0; |
| 941 | ip->ip_len = htons(ip_size); |
| 942 | ip->ip_id = sm->ip_hdr->ip_id; |
| 943 | ip->ip_off = 0; |
| 944 | ip->ip_ttl = 255; |
| 945 | ip->ip_p = IPPROTO_SCTP; |
| 946 | /* |
| 947 | The definitions below should be removed when they make it into the SCTP stack |
| 948 | */ |
| 949 | #define SCTP_MIDDLEBOX_FLAG 0x02 |
| 950 | #define SCTP_NAT_TABLE_COLLISION 0x00b0 |
| 951 | #define SCTP_MISSING_NAT 0x00b1 |
| 952 | chunk_hdr->chunk_type = (sndrply & SN_TX_ABORT) ? SCTP_ABORT_ASSOCIATION : SCTP_OPERATION_ERROR; |
| 953 | chunk_hdr->chunk_flags = SCTP_MIDDLEBOX_FLAG; |
| 954 | if (include_error_cause) { |
| 955 | error_cause->code = htons((sndrply & SN_REFLECT_ERROR) ? SCTP_MISSING_NAT : SCTP_NAT_TABLE_COLLISION); |
| 956 | error_cause->length = htons(sizeof(struct sctp_error_cause)); |
| 957 | chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr) + sizeof(struct sctp_error_cause)); |
| 958 | } else { |
| 959 | chunk_hdr->chunk_length = htons(sizeof(*chunk_hdr)); |
| 960 | } |
| 961 | |
| 962 | /* set specific values */ |
| 963 | switch (sndrply) { |
| 964 | case SN_REFLECT_ERROR: |
| 965 | chunk_hdr->chunk_flags |= SCTP_HAD_NO_TCB; /* set Tbit */ |
| 966 | sctp_hdr->v_tag = sm->sctp_hdr->v_tag; |
| 967 | break; |
| 968 | case SN_REPLY_ERROR: |
| 969 | sctp_hdr->v_tag = (direction == SN_TO_LOCAL) ? assoc->g_vtag : assoc->l_vtag ; |
| 970 | break; |
| 971 | case SN_SEND_ABORT: |
| 972 | sctp_hdr->v_tag = sm->sctp_hdr->v_tag; |
| 973 | break; |
| 974 | case SN_REPLY_ABORT: |
no test coverage detected