diff options
Diffstat (limited to 'src/dns/dnsparser.c')
-rw-r--r-- | src/dns/dnsparser.c | 329 |
1 files changed, 1 insertions, 328 deletions
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c index 2e9e73f1c..12253a2e7 100644 --- a/src/dns/dnsparser.c +++ b/src/dns/dnsparser.c | |||
@@ -793,331 +793,4 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p, | |||
793 | return GNUNET_OK; | 793 | return GNUNET_OK; |
794 | } | 794 | } |
795 | 795 | ||
796 | 796 | /* end of dnsparser.c */ | |
797 | |||
798 | |||
799 | |||
800 | |||
801 | |||
802 | |||
803 | |||
804 | |||
805 | |||
806 | |||
807 | |||
808 | |||
809 | |||
810 | |||
811 | |||
812 | |||
813 | |||
814 | |||
815 | |||
816 | |||
817 | |||
818 | |||
819 | |||
820 | |||
821 | |||
822 | |||
823 | |||
824 | |||
825 | /* legacy code follows */ | ||
826 | |||
827 | /** | ||
828 | * Parse a name from DNS to a normal .-delimited, 0-terminated string. | ||
829 | * | ||
830 | * @param d The destination of the name. Should have at least 255 bytes allocated. | ||
831 | * @param src The DNS-Packet | ||
832 | * @param idx The offset inside the Packet from which on the name should be read | ||
833 | * @returns The offset of the first unparsed byte (the byte right behind the name) | ||
834 | */ | ||
835 | static unsigned int | ||
836 | parse_dns_name (char *d, const unsigned char *src, unsigned short idx) | ||
837 | { /*{{{ */ | ||
838 | char *dest = d; | ||
839 | |||
840 | int len = src[idx++]; | ||
841 | |||
842 | while (len != 0) | ||
843 | { | ||
844 | if (len & 0xC0) | ||
845 | { /* Compressed name, offset in this and the next octet */ | ||
846 | unsigned short offset = ((len & 0x3F) << 8) | src[idx++]; | ||
847 | |||
848 | parse_dns_name (dest, src, offset - 12); /* 12 for the Header of the DNS-Packet, idx starts at 0 which is 12 bytes from the start of the packet */ | ||
849 | return idx; | ||
850 | } | ||
851 | memcpy (dest, src + idx, len); | ||
852 | idx += len; | ||
853 | dest += len; | ||
854 | *dest = '.'; | ||
855 | dest++; | ||
856 | len = src[idx++]; | ||
857 | }; | ||
858 | *dest = 0; | ||
859 | |||
860 | return idx; | ||
861 | } | ||
862 | |||
863 | /*}}}*/ | ||
864 | |||
865 | /** | ||
866 | * Parse a complete DNS-Record from raw DNS-data to a struct dns_record | ||
867 | * | ||
868 | * @param data The DNS-data | ||
869 | * @param dst Pointer to count pointers; individual pointers will be allocated | ||
870 | * @param count Number of records to parse | ||
871 | * @param idx The offset inside the Packet from which on the name should be read | ||
872 | * @returns The offset of the first unparsed byte (the byte right behind the last record) | ||
873 | */ | ||
874 | static unsigned short | ||
875 | parse_dns_record (unsigned char *data, /*{{{ */ | ||
876 | struct dns_record **dst, unsigned short count, | ||
877 | unsigned short idx) | ||
878 | { | ||
879 | int i; | ||
880 | unsigned short _idx; | ||
881 | |||
882 | for (i = 0; i < count; i++) | ||
883 | { | ||
884 | dst[i] = GNUNET_malloc (sizeof (struct dns_record)); | ||
885 | dst[i]->name = alloca (255); // see RFC1035, no name can be longer than this. | ||
886 | char *name = dst[i]->name; | ||
887 | |||
888 | _idx = parse_dns_name (name, data, idx); | ||
889 | dst[i]->namelen = _idx - idx; | ||
890 | |||
891 | dst[i]->name = GNUNET_malloc (dst[i]->namelen); | ||
892 | memcpy (dst[i]->name, name, dst[i]->namelen); | ||
893 | |||
894 | idx = _idx; | ||
895 | |||
896 | dst[i]->type = *((unsigned short *) (data + idx)); | ||
897 | idx += 2; | ||
898 | dst[i]->class = *((unsigned short *) (data + idx)); | ||
899 | idx += 2; | ||
900 | dst[i]->ttl = *((unsigned int *) (data + idx)); | ||
901 | idx += 4; | ||
902 | dst[i]->data_len = *((unsigned short *) (data + idx)); | ||
903 | idx += 2; | ||
904 | dst[i]->data = GNUNET_malloc (ntohs (dst[i]->data_len)); | ||
905 | memcpy (dst[i]->data, data + idx, ntohs (dst[i]->data_len)); | ||
906 | idx += ntohs (dst[i]->data_len); | ||
907 | } | ||
908 | return idx; | ||
909 | } /*}}} */ | ||
910 | |||
911 | /** | ||
912 | * Parse a raw DNS-Packet into an usable struct | ||
913 | */ | ||
914 | struct dns_pkt_parsed * | ||
915 | parse_dns_packet (struct dns_pkt *pkt) | ||
916 | { /*{{{ */ | ||
917 | struct dns_pkt_parsed *ppkt = GNUNET_malloc (sizeof (struct dns_pkt_parsed)); | ||
918 | |||
919 | memcpy (&ppkt->s, &pkt->s, sizeof pkt->s); | ||
920 | |||
921 | unsigned short qdcount = ntohs (ppkt->s.qdcount); | ||
922 | unsigned short ancount = ntohs (ppkt->s.ancount); | ||
923 | unsigned short nscount = ntohs (ppkt->s.nscount); | ||
924 | unsigned short arcount = ntohs (ppkt->s.arcount); | ||
925 | |||
926 | ppkt->queries = GNUNET_malloc (qdcount * sizeof (struct dns_query *)); | ||
927 | ppkt->answers = GNUNET_malloc (ancount * sizeof (struct dns_record *)); | ||
928 | ppkt->nameservers = GNUNET_malloc (nscount * sizeof (struct dns_record *)); | ||
929 | ppkt->additional = GNUNET_malloc (arcount * sizeof (struct dns_record *)); | ||
930 | |||
931 | unsigned short idx = 0, _idx; /* This keeps track how far we have parsed the data */ | ||
932 | |||
933 | /* Parse the Query */ | ||
934 | int i; | ||
935 | |||
936 | for (i = 0; i < qdcount; i++) | ||
937 | { /*{{{ */ | ||
938 | ppkt->queries[i] = GNUNET_malloc (sizeof (struct dns_query)); | ||
939 | char *name = alloca (255); /* see RFC1035, it can't be more than this. */ | ||
940 | |||
941 | _idx = parse_dns_name (name, pkt->data, idx); | ||
942 | ppkt->queries[i]->namelen = _idx - idx; | ||
943 | idx = _idx; | ||
944 | |||
945 | ppkt->queries[i]->name = GNUNET_malloc (ppkt->queries[i]->namelen); | ||
946 | memcpy (ppkt->queries[i]->name, name, ppkt->queries[i]->namelen); | ||
947 | |||
948 | ppkt->queries[i]->qtype = *((unsigned short *) (pkt->data + idx)); | ||
949 | idx += 2; | ||
950 | ppkt->queries[i]->qclass = *((unsigned short *) (pkt->data + idx)); | ||
951 | idx += 2; | ||
952 | } | ||
953 | /*}}} */ | ||
954 | idx = parse_dns_record (pkt->data, ppkt->answers, ancount, idx); | ||
955 | idx = parse_dns_record (pkt->data, ppkt->nameservers, nscount, idx); | ||
956 | idx = parse_dns_record (pkt->data, ppkt->additional, arcount, idx); | ||
957 | return ppkt; | ||
958 | } /*}}} */ | ||
959 | |||
960 | static void | ||
961 | unparse_dns_name (char *dest, char *src, size_t len) | ||
962 | { | ||
963 | char *b = dest; | ||
964 | char cnt = 0; | ||
965 | |||
966 | dest++; | ||
967 | while (*src != 0) | ||
968 | { | ||
969 | while (*src != '.' && *src != 0) | ||
970 | { | ||
971 | *dest = *src; | ||
972 | src++; | ||
973 | dest++; | ||
974 | cnt++; | ||
975 | } | ||
976 | *b = cnt; | ||
977 | cnt = 0; | ||
978 | b = dest; | ||
979 | dest++; | ||
980 | src++; | ||
981 | } | ||
982 | *b = 0; | ||
983 | } | ||
984 | |||
985 | struct dns_pkt * | ||
986 | unparse_dns_packet (struct dns_pkt_parsed *ppkt) | ||
987 | { | ||
988 | size_t size = sizeof (struct dns_pkt) - 1; | ||
989 | int i; | ||
990 | |||
991 | for (i = 0; i < ntohs (ppkt->s.qdcount); i++) | ||
992 | size += ppkt->queries[i]->namelen + 1; | ||
993 | |||
994 | for (i = 0; i < ntohs (ppkt->s.ancount); i++) | ||
995 | { | ||
996 | size += ppkt->answers[i]->namelen + 1; | ||
997 | size += ppkt->answers[i]->data_len; | ||
998 | } | ||
999 | for (i = 0; i < ntohs (ppkt->s.nscount); i++) | ||
1000 | { | ||
1001 | size += ppkt->nameservers[i]->namelen + 1; | ||
1002 | size += ppkt->nameservers[i]->data_len; | ||
1003 | } | ||
1004 | for (i = 0; i < ntohs (ppkt->s.arcount); i++) | ||
1005 | { | ||
1006 | size += ppkt->additional[i]->namelen + 1; | ||
1007 | size += ppkt->additional[i]->data_len; | ||
1008 | } | ||
1009 | |||
1010 | size += | ||
1011 | 4 * ntohs (ppkt->s.qdcount) + 10 * (ntohs (ppkt->s.ancount) + | ||
1012 | ntohs (ppkt->s.arcount) + | ||
1013 | ntohs (ppkt->s.nscount)); | ||
1014 | |||
1015 | struct dns_pkt *pkt = GNUNET_malloc (size); | ||
1016 | char *pkt_c = (char *) pkt; | ||
1017 | |||
1018 | memcpy (&pkt->s, &ppkt->s, sizeof ppkt->s); | ||
1019 | size_t idx = sizeof ppkt->s; | ||
1020 | |||
1021 | for (i = 0; i < ntohs (ppkt->s.qdcount); i++) | ||
1022 | { | ||
1023 | unparse_dns_name (&pkt_c[idx], ppkt->queries[i]->name, | ||
1024 | ppkt->queries[i]->namelen); | ||
1025 | idx += ppkt->queries[i]->namelen; | ||
1026 | struct dns_query_line *d = (struct dns_query_line *) &pkt_c[idx]; | ||
1027 | |||
1028 | d->class = ppkt->queries[i]->qclass; | ||
1029 | d->type = ppkt->queries[i]->qtype; | ||
1030 | idx += sizeof (struct dns_query_line); | ||
1031 | } | ||
1032 | |||
1033 | for (i = 0; i < ntohs (ppkt->s.ancount); i++) | ||
1034 | { | ||
1035 | unparse_dns_name (&pkt_c[idx], ppkt->answers[i]->name, | ||
1036 | ppkt->answers[i]->namelen); | ||
1037 | idx += ppkt->answers[i]->namelen; | ||
1038 | struct dns_record_line *r = (struct dns_record_line *) &pkt_c[idx]; | ||
1039 | |||
1040 | r->type = ppkt->answers[i]->type; | ||
1041 | r->class = ppkt->answers[i]->class; | ||
1042 | r->ttl = ppkt->answers[i]->ttl; | ||
1043 | r->data_len = ppkt->answers[i]->data_len; | ||
1044 | idx += sizeof (struct dns_record_line); | ||
1045 | memcpy (&r->data, ppkt->answers[i]->data, ppkt->answers[i]->data_len); | ||
1046 | idx += ppkt->answers[i]->data_len; | ||
1047 | } | ||
1048 | |||
1049 | for (i = 0; i < ntohs (ppkt->s.nscount); i++) | ||
1050 | { | ||
1051 | unparse_dns_name (&pkt_c[idx], ppkt->nameservers[i]->name, | ||
1052 | ppkt->nameservers[i]->namelen); | ||
1053 | idx += ppkt->nameservers[i]->namelen; | ||
1054 | struct dns_record_line *r = (struct dns_record_line *) &pkt_c[idx]; | ||
1055 | |||
1056 | r->type = ppkt->nameservers[i]->type; | ||
1057 | r->class = ppkt->nameservers[i]->class; | ||
1058 | r->ttl = ppkt->nameservers[i]->ttl; | ||
1059 | r->data_len = ppkt->nameservers[i]->data_len; | ||
1060 | idx += sizeof (struct dns_record_line); | ||
1061 | memcpy (&r->data, ppkt->nameservers[i]->data, | ||
1062 | ppkt->nameservers[i]->data_len); | ||
1063 | idx += ppkt->nameservers[i]->data_len; | ||
1064 | } | ||
1065 | |||
1066 | for (i = 0; i < ntohs (ppkt->s.arcount); i++) | ||
1067 | { | ||
1068 | unparse_dns_name (&pkt_c[idx], ppkt->additional[i]->name, | ||
1069 | ppkt->additional[i]->namelen); | ||
1070 | idx += ppkt->additional[i]->namelen; | ||
1071 | struct dns_record_line *r = (struct dns_record_line *) &pkt_c[idx]; | ||
1072 | |||
1073 | r->type = ppkt->additional[i]->type; | ||
1074 | r->class = ppkt->additional[i]->class; | ||
1075 | r->ttl = ppkt->additional[i]->ttl; | ||
1076 | r->data_len = ppkt->additional[i]->data_len; | ||
1077 | idx += sizeof (struct dns_record_line); | ||
1078 | memcpy (&r->data, ppkt->additional[i]->data, ppkt->additional[i]->data_len); | ||
1079 | idx += ppkt->additional[i]->data_len; | ||
1080 | } | ||
1081 | |||
1082 | return pkt; | ||
1083 | } | ||
1084 | |||
1085 | void | ||
1086 | free_parsed_dns_packet (struct dns_pkt_parsed *ppkt) | ||
1087 | { | ||
1088 | unsigned short qdcount = ntohs (ppkt->s.qdcount); | ||
1089 | unsigned short ancount = ntohs (ppkt->s.ancount); | ||
1090 | unsigned short nscount = ntohs (ppkt->s.nscount); | ||
1091 | unsigned short arcount = ntohs (ppkt->s.arcount); | ||
1092 | |||
1093 | int i; | ||
1094 | |||
1095 | for (i = 0; i < qdcount; i++) | ||
1096 | { | ||
1097 | GNUNET_free (ppkt->queries[i]->name); | ||
1098 | GNUNET_free (ppkt->queries[i]); | ||
1099 | } | ||
1100 | GNUNET_free (ppkt->queries); | ||
1101 | for (i = 0; i < ancount; i++) | ||
1102 | { | ||
1103 | GNUNET_free (ppkt->answers[i]->name); | ||
1104 | GNUNET_free (ppkt->answers[i]->data); | ||
1105 | GNUNET_free (ppkt->answers[i]); | ||
1106 | } | ||
1107 | GNUNET_free (ppkt->answers); | ||
1108 | for (i = 0; i < nscount; i++) | ||
1109 | { | ||
1110 | GNUNET_free (ppkt->nameservers[i]->name); | ||
1111 | GNUNET_free (ppkt->nameservers[i]->data); | ||
1112 | GNUNET_free (ppkt->nameservers[i]); | ||
1113 | } | ||
1114 | GNUNET_free (ppkt->nameservers); | ||
1115 | for (i = 0; i < arcount; i++) | ||
1116 | { | ||
1117 | GNUNET_free (ppkt->additional[i]->name); | ||
1118 | GNUNET_free (ppkt->additional[i]->data); | ||
1119 | GNUNET_free (ppkt->additional[i]); | ||
1120 | } | ||
1121 | GNUNET_free (ppkt->additional); | ||
1122 | GNUNET_free (ppkt); | ||
1123 | } | ||