aboutsummaryrefslogtreecommitdiff
path: root/src/dns/dnsparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dns/dnsparser.c')
-rw-r--r--src/dns/dnsparser.c329
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 */
835static unsigned int
836parse_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 */
874static unsigned short
875parse_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 */
914struct dns_pkt_parsed *
915parse_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
960static void
961unparse_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
985struct dns_pkt *
986unparse_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
1085void
1086free_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}