<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _read_ipv4_options(self, size=None):
 """Read IPv4 option list. Positional arguments: * size -- int, buffer size Returns: * tuple -- IPv4 option list * dict -- extracted IPv4 option """

        counter = 0         # length of read option list
        optkind = list()    # option kind list
        options = dict()    # dict of option data

        while counter < size:
            # get option kind
            kind = self._read_unpack(1)

            # fetch corresponding option tuple
            opts = IPv4_OPT.get(kind)
            if opts is None:
                len_ = size - counter
                counter = size
                options['Unknown'] = self._read_fileng(len_)
                break

            # extract option
            dscp = OPT_TYPE.get(kind)
            desc = dscp.name
            if opts[0]:
                byte = self._read_unpack(1)
                if byte:    # check option process mode
                    data = process_opt[opts[2]](self, byte, kind)
                else:       # permission options (length is 2)
                    data = dict(
                        kind=kind,                          # option kind
                        type=self._read_opt_type(kind),     # option type info
                        length=2,                           # option length
                        flag=True,                          # permission flag
                    )
            else:           # 1-bytes options
                byte = 1

                data = dict(
                    kind=kind,                          # option kind
                    type=self._read_opt_type(kind),     # option type info
                    length=1,                           # option length
                )

            # record option data
            counter += byte
            if dscp in optkind:
                if isinstance(options[desc], tuple):
                    options[desc] += (Info(data),)
                else:
                    options[desc] = (Info(options[desc]), Info(data))
            else:
                optkind.append(dscp)
                options[desc] = data

            # break when eol triggered
            if not kind:
                break

        # get padding
        if counter < size:
            len_ = size - counter
            self._read_binary(len_)

        return tuple(optkind), options