/************************************************************************* * * Receive and verify an incoming packet. * *************************************************************************/ static int recv_disc( struct session *ses, struct pppoe_packet *p){ int error = 0; unsigned int from_len = sizeof(struct sockaddr_ll); p->hdr = (struct pppoe_hdr*)p->buf; error = recvfrom( disc_sock, p->buf, 1500, 0, (struct sockaddr*)&p->addr, &from_len); if(error < 0) return error; extract_tags(p->hdr,p->tags); return 1; }
/************************************************************************* * * Construct and send a discovery message. * ************************************************************************/ int send_disc(struct session *ses, struct pppoe_packet *p) { char buf[MAX_PAYLOAD + sizeof(struct pppoe_hdr)]; int data_len = sizeof(struct pppoe_hdr); struct pppoe_hdr *ph = NULL; struct pppoe_tag *tag = NULL; int i, err = 0; int got_host_uniq = 0; int got_srv_name = 0; int got_ac_name = 0; for (i = 0; i < MAX_TAGS; i++) { if (!p->tags[i]) continue; got_host_uniq |= (p->tags[i]->tag_type == PTT_HOST_UNIQ); /* Relay identifiers qualify as HOST_UNIQ's: we need HOST_UNIQ to uniquely identify the packet, PTT_RELAY_SID is sufficient for us for outgoing packets */ got_host_uniq |= (p->tags[i]->tag_type == PTT_RELAY_SID); got_srv_name |= (p->tags[i]->tag_type == PTT_SRV_NAME); got_ac_name |= (p->tags[i]->tag_type == PTT_AC_NAME); data_len += (ntohs(p->tags[i]->tag_len) + sizeof(struct pppoe_tag)); } ph = (struct pppoe_hdr *) buf; memcpy(ph, p->hdr, sizeof(struct pppoe_hdr)); ph->length = __constant_htons(0); /* if no HOST_UNIQ tags --- add one with process id */ if (!got_host_uniq){ data_len += (sizeof(struct pppoe_tag) + sizeof(struct session *)); tag = next_tag(ph); tag->tag_type = PTT_HOST_UNIQ; tag->tag_len = htons(sizeof(struct session *)); memcpy(tag->tag_data, &ses, sizeof(struct session *)); add_tag(ph, tag); } if( !got_srv_name ){ data_len += sizeof(struct pppoe_tag); tag = next_tag(ph); tag->tag_type = PTT_SRV_NAME; tag->tag_len = 0; add_tag(ph, tag); } if(!got_ac_name && ph->code==PADO_CODE){ data_len += sizeof(struct pppoe_tag); tag = next_tag(ph); tag->tag_type = PTT_AC_NAME; tag->tag_len = 0; add_tag(ph, tag); } for (i = 0; i < MAX_TAGS; i++) { if (!p->tags[i]) continue; tag = next_tag(ph); memcpy(tag, p->tags[i], sizeof(struct pppoe_tag) + ntohs(p->tags[i]->tag_len)); add_tag(ph, tag); } /* Now fixup the packet struct to make sure all of its pointers are self-contained */ memcpy( p->hdr , ph, data_len ); extract_tags( p->hdr, p->tags); err = sendto(disc_sock, buf, data_len, 0, (struct sockaddr*) &p->addr, sizeof(struct sockaddr_ll)); if(err < 0) poe_error(ses,"sendto returned: %m\n"); return err; }
int read_asf_header(struct fidinfo *fidinfo, struct statex *statex, FILE *fp) { static unsigned char buffer[2048]; char tagvalue[256]; int pos, endpos; char *string = NULL; int bitrate = 0; int channels = 0; int duration; int samplerate; char *text_buf; while(!feof(fp)) { pos = ftell(fp); fread((char*) &objh, sizeof(objh), 1, fp); le2me_ASF_obj_header_t(&objh); if (feof(fp)) break; endpos = pos + objh.size; switch(ASF_LOAD_GUID_PREFIX(objh.guid)) { case ASF_GUID_PREFIX_file_header: /* get bitrate and duration from this header */ fread((char*) &fileh, sizeof(fileh), 1, fp); le2me_ASF_file_header_t(&fileh); bitrate = (int)(fileh.max_bitrate / 1000); duration = (int)(fileh.play_duration / 10000 - fileh.preroll); sprintf(tagvalue, "%d", duration); fidinfo->tagvalues[TAG_DURATION_NUM] = strdup(tagvalue); break; case ASF_GUID_PREFIX_content_desc: /* get title, artist and comment from this header */ fread((char*) &contenth, sizeof(contenth), 1, fp); le2me_ASF_content_description_t(&contenth); /* title */ if (contenth.title_size != 0) { string = (char*)malloc(contenth.title_size); fread(string, contenth.title_size, 1, fp); if (contenth.title_size) fidinfo->tagvalues[TAG_TITLE_NUM] = strdup(utf16tointernal(string, contenth.title_size)); } /* author */ if (contenth.author_size != 0) { string = (char*)realloc((void*)string, contenth.author_size); fread(string, contenth.author_size, 1, fp); if (contenth.author_size) fidinfo->tagvalues[TAG_ARTIST_NUM] = strdup(utf16tointernal(string, contenth.author_size)); } /* copyright */ if (contenth.copyright_size != 0) { string = (char*)realloc((void*)string, contenth.copyright_size); fread(string, contenth.copyright_size, 1, fp); /* ignore */ } /* comment */ if (contenth.comment_size != 0) { string = (char*)realloc((void*)string, contenth.comment_size); fread(string, contenth.comment_size, 1, fp); if (contenth.comment_size) fidinfo->tagvalues[TAG_COMMENT_NUM] = nullifempty(strdup(utf16tointernal(string, contenth.comment_size))); } /* rating */ if (contenth.rating_size != 0) { string = (char*)realloc((void*)string, contenth.rating_size); fread(string, contenth.rating_size, 1, fp); /* ignore */ } free(string); break; case ASF_GUID_PREFIX_stream_header: /* get number of channels and samplerate from this header */ fread((char*) &streamh, sizeof(streamh), 1, fp); le2me_ASF_stream_header_t(&streamh); if (streamh.type_size > 2048 || streamh.stream_size > 2048) { fprintf(stderr, "%s: ASF header size bigger than 2048 bytes (%d, %d)!\n" "Please contact %s authors, and upload/send this file.\n", progopts.progname, (int)streamh.type_size, (int)streamh.stream_size, progopts.progname); return 0; } fread((char*) buffer, streamh.type_size, 1, fp); if (ASF_LOAD_GUID_PREFIX(streamh.type) == ASF_GUID_PREFIX_audio_stream) { memcpy(&wfh, buffer, sizeof(ASF_waveformatex_t)); le2me_ASF_waveformatex_t(wfh); channels = (int) wfh.nChannels; samplerate = (int) wfh.nSamplesPerSec; sprintf(tagvalue, "%d", samplerate); fidinfo->tagvalues[TAG_SAMPLERATE_NUM] = strdup(tagvalue); } break; case ASF_GUID_PREFIX_text_tags: /* get id3-like tags from this header */ text_buf = (char*) malloc(objh.size); fread((char*) text_buf, objh.size, 1, fp); extract_tags(fidinfo, text_buf, objh.size); free(text_buf); break; case ASF_GUID_PREFIX_unknown_drm_1: /* if this header exists, then the tune is drm-protected */ fidinfo->tagvalues[TAG_DRM_NUM] = "msasf"; break; } fseek(fp, endpos, SEEK_SET); } /* codec */ fidinfo->tagvalues[TAG_CODEC_NUM] = "wma"; /* offset */ fidinfo->tagvalues[TAG_OFFSET_NUM] = "0"; /* trailer */ fidinfo->tagvalues[TAG_TRAILER_NUM] = "0"; /* bitrate */ sprintf(tagvalue, "f%s%d", channels > 1 ? "s" : "m", bitrate); fidinfo->tagvalues[TAG_BITRATE_NUM] = strdup(tagvalue); /* rid */ fidinfo->tagvalues[TAG_RID_NUM] = calculaterid(fp, 0, statex->size); return 1; }